Beginning Mocking With Moq 3 – Part 3

Writing

Other parts in this series

Part 1

Part 2

In the previous part of this series, we looked at how you can verify on an interface exactly what was called using Moq’s “Verify” syntax. In this entry we are going to take a look at setting up mocks with return values.

Setting Up Return Values

If you have ever done mocking before in the past then you probably know that the “classic” way of using mocks is to setup the mock before you call it. So in the last post when we had this line:

mockFileWriter.Verify(fw => fw.WriteLine("1001,10.53"), Times.Exactly(1));

which verifies, after the fact, what was called. In the “classic” way of doing things we could have written the test like this: (In Moq 2 the method was called “Expect” not “Setup”)

[Fact]
public void it_should_pass_data_to_file_writer2()
{
    var order = new Order();
    order.OrderId = 1001;
    order.OrderTotal = 10.53M;

    var mockFileWriter = new Mock<IFileWriter>();
    mockFileWriter.Setup(fw => fw.WriteLine("1001,10.53")).AtMostOnce();

    var orderWriter = new OrderWriter(mockFileWriter.Object);    
    orderWriter.WriteOrder(order);

    mockFileWriter.VerifyAll();
}

Here you can see that right after we declare the mock we call “Setup” and pass the expectation to it. We then call “AtMostOnce” to make sure that it is only called a single time. After that we actually perform our test actions. At this point though we haven’t asserted anything, so we have to call “VerifyAll” on the mock that was created. This causes all setup calls to be verified, and an exception will be raised if one of the expectations weren’t met.

So the “Verify” syntax seems so much better, we don’t need to do two calls, or remember to call “VerifyAll” after the fact. So why is the original Setup syntax still there? Well, besides backward compatibility. Part of the reason is that there is one key thing that you can’t do after the fact, and that is setting up return values on method calls. Let’s start this by creating an OrderReader class which uses an IFileReader interface. The IFileReader interface has a line called “ReadLine” which returns a string.

Since we want to mock this IFileReader and call this method on it that returns a value, we need some way to setup the return value. Thanksfully, Moq provides us with an extremely easy way to do this:

public override void EstablishContext()
{
    var mockFileReader = new Mock<IFileReader>();
    mockFileReader.Setup(fr => fr.ReadLine()).Returns("1002,10.34");

    orderReader = new OrderReader(mockFileReader.Object);
}

public override void Because()
{
    order = orderReader.ReadOrder();
}

Moq can see the return type of the method that you are passing in, and then lets you return back an instance of that type. In fact, if a method is returning another interface that you need to mock, then you can return a mock type! This let’s you build up more complex interfaces from mocks.

Now that we have setup the mock and created our order, we simply call the “ReadOrder” method and we get back an order object. All that is left to assert now is that the line from the IFileReader was parsed and turned back into an order correctly:

[Fact]
public void it_should_have_order_id_set()
{            
    Assert.Equal(1002, order.OrderId);            
}

[Fact]
public void it_should_have_order_total_set()
{
    Assert.Equal(10.34M, order.OrderTotal);
}

And that was easy. But I mentioned earlier that we are able to setup two mocks and have one mock returned from the other mock. How does that work?

Returning Mocks From Other Mocks

Well, it works just like you are passing a mock to any other method. So if we have two interfaces like this:

internal interface IDoSomething
{
    IDoSomethingElse GetSomethingElse();
}

internal interface IDoSomethingElse
{
    string GetSomeValue();
}

Then it is as simple as doing this:

var mockSomethingElse = new Mock<IDoSomethingElse>();
mockSomethingElse.Setup(mse => mse.GetSomeValue()).Returns("Something");

var mockSomething = new Mock<IDoSomething>();
mockSomething.Setup(ms => ms.GetSomethingElse()).Returns(mockSomethingElse.Object);

And there you have it, we have created the IDoSomethingElse mock and setup expectations on its return value. Then we mock IDoSomething and when we setup its method, we simply pass the mock.Object into the “Returns” method.

Summary

In this post we have looked at setting up return values on mocks so that we can return canned values from them to satisfy the needs of calling classes. If you are setting up return values on mocks and not really verifying anything that was called on the mock, then technically you are not mocking, but instead stubbing. I guess that is a topic for another day though. I hope you enjoyed this entry, and stay tuned for the next post when we will look at mocking multiple interfaces and callbacks.

Comments (14)

  1. You should do a fourth part to your series to discuss verifying method calls during an expected exception test. I ran into all sorts of trouble doing verifications even though I was deliberately setting up false expectations.

    It turned out that because the method I was testing throws (as expected), my VerifyAll method calls were not actually executed as part of the test, simply because the tested method threw as expected.

    The solution to this problem is to wrap your test method in a try block and your verify method calls into a finally block. For example:

    mock.Setup(c => c.MyMethod());
    try
    {
    testObject.TestedMethod(); // throws WtfException
    }
    finally
    {
    mock.VerifyAll();
    }

  2. mockFileReader.Setup(fr => fr.ReadLine()).Returns("1002,10.34");

    The above line gives me the following error:

    ‘Moq.Language.Flow.ISetup<Moq1.IFileReader>’ does not contain a definition for ‘Returns’ and no extension method ‘Returns’ accepting a first argument of type ‘Moq.Language.Flow.ISetup<Moq1.IFileReader>’ could be found (are you missing a using directive or an assembly reference?)

  3. First off, I appreciate you doing this series. One of the things that I’m struggling with is that without a lot of context, it’s hard to see what some of the mocking of things really proves.

    Given above info regarding returning mocks from mocks. I’m not getting the value of such an exercise. I took snippets from above and filled in the blanks. Commenting out the setup of the mockSomethingElse does not break the test. In fact, removing the ".Returns(mockSomethingElse.Object)" doesn’t break the test.

    Could you come up with a concrete case where you need to do something like this? Thanks

    [Fact]
    public void mock_of_a_mock()
    {
    var mockSomethingElse = new Mock<IDoSomethingElse>();
    // mockSomethingElse.Setup(mse => mse.GetSomeValue()).Returns("Something");

    var mockSomething = new Mock<IDoSomething>();
    mockSomething.Setup(ms => ms.GetSomethingElse()).Returns(mockSomethingElse.Object);

    var cut = new ClassUnderTest(mockSomething.Object);
    cut.MakeTheCall();

    mockSomething.VerifyAll();

    }

    public ClassUnderTest(IDoSomething something)
    {
    this.something = something;
    }
    public void MakeTheCall()
    {
    something.GetSomethingElse();
    }
    }

    // he had internal, originally made public
    public interface IDoSomething
    {
    IDoSomethingElse GetSomethingElse();
    }

    public interface IDoSomethingElse
    {
    string GetSomeValue();
    }

  4. Here is NUNIT Testexample (without Order and OrderWriter class because i had troubles at beginning:

    [TestClass]
    public class When_an_order_is_to_be_written_to_disk
    {

    private Order order;
    private Mock mockFileWriter;
    private OrderWriter orderWriter;

    [TestInitialize]
    public void Init()
    {
    order = new Order();
    order.OrderId = 1001;
    order.OrderTotal = 11;

    mockFileWriter = new Mock();
    orderWriter = new OrderWriter(mockFileWriter.Object);

    }

    [TestMethod]
    public void it_should_pass_data_to_file_writer()
    {
    orderWriter.WriteOrder(order);
    mockFileWriter.Verify(fw => fw.WriteLine(“1001,11”), Times.Exactly(1));
    mockFileWriter.Verify(fw => fw.WriteLine(It.Is(s => s.Length > 3)), Times.Exactly(1));
    }
    }

  5. @Dan

    Returning mock from mocks is useful when using abstract factory pattern. In that case you are mocking both the factory and the objects(interfaces) that the factory returns.

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

More Insights

View All