views:

106

answers:

1

I've just been working on some tests using Moq but ran into trouble trying to test a method I wanted to call twice through a try catch block. The principle is that the first call throws an exception, then in the catch I correct the problem and call the method again.

I managed to do it with Rhino Mocks as below but being new to both frameworks I wondered if anyone could tell me if the same can be achieved using Moq.

// C.U.T
public class Mockee
{
    bool theCatLives = true;

    public Mockee() { }

    public virtual void SetFalse()
    {
        theCatLives = false;
    }
}


[Test]
public void TestTryCatch(){

    var mr = new MockRepository();
    var mock = mr.StrictMock<Mockee>();
    mr.Record();
    Expect.Call(mock.SetFalse).Throw(new Exception());
    Expect.Call(mock.SetFalse);
    mr.ReplayAll();

    try
    {
        mock.SetFalse();
    }
    catch
    {
        mock.SetFalse();
    }

    mock.VerifyAllExpectations();
}
+2  A: 

This isn't particularly easy to do with Moq, as it has no concept of ordered expectations. You can, however, use the Callback method and throw exceptions from there, like this:

var actions = new Queue<Action>(new Action[] 
{
    () => { throw new Exception(); },
    () => { } 
});

var mock = new Mock<Mockee>();
mock.Setup(m => m.SetFalse()).Callback(() => actions.Dequeue()()).Verifiable();

try
{
    mock.Object.SetFalse();
}
catch
{
    mock.Object.SetFalse();
}
mock.Verify();

However, one caveat is that this version only checks whether the SetFalse method was called at all.

If you want to verify that it was called twice, you can change the last statement to this:

mock.Verify(m => m.SetFalse(), Times.Exactly(2));

However, this slightly violates the DRY principle because you would be stating the same Setup twice, but you could get around that by first declaring and defining a variable of type Expression<Action<Mockee>> and use it for both the Setup and the Verify methods...

Mark Seemann
Thanks, I hadn't played with CallBack() yet, that looks like fun!
panamack