Kash Farooq's software development blog

.NET Developer

Archive for the ‘Moq’ Category

Using Moq callbacks to check complex arguments sent to a dependency

Posted by Kash Farooq on June 16, 2013

I’ve written before about the various ways you can test the contents of a complex parameter sent to a dependency. The messages you see in RhinoMocks and Moq when a test fails aren’t always clear.

You can use Moq callbacks to give clear test failure messages.

Consider the system under test. Your creating an order, and using some of the data in the order object to create a customer. Obviously, you would have written this code test-driven – the aim of the test would be to ensure the customer object is created properly.

public class OrderService
{
  private readonly ICustomerService _customerService;

  public OrderService(ICustomerService customerService)
  {
    _customerService = customerService;
  }

  public void CreateOrder(Order order, int createdBy)
  {
     var customer = new Customer
        {
           FirstName = order.FirstName,
           LastName = order.FirstName //intentional bug
        };
    _customerService.Save(customer, createdBy);

    //TODO: do some other stuff with the order.
  }
}

In a test, let’s just use Moq’s Verify method and you’ll see what I mean about clear failure messages:

[Test]
public void WhenCreatingAnOrderSaveTheCustomerDetails()
{
  const int orderCreatedByPersonId = 1;

  var customerServiceMock = new Mock<ICustomerService>();

  var orderService = new OrderService(customerServiceMock.Object);
  orderService.CreateOrder(new Order { FirstName = "John", LastName = "Smith", OrderItems = new List<OrderItem>() }, orderCreatedByPersonId);

  customerServiceMock.Verify(x => x.Save(It.Is<Customer>(y => y.FirstName == "John" && y.LastName == "Smith"), orderCreatedByPersonId));
}

And this is the error you’ll see:

Moq.MockException :
Expected invocation on the mock at least once, but was never performed: x => x.Save(It.Is<Customer>(y => y.FirstName == "John" && y.LastName == "Smith"), 1)
No setups configured.

Performed invocations:
ICustomerService.Save(Customer, 1)

I don’t like this error message. You can’t tell what caused the failure. You can see that ICustomerService.Save was called with a Customer object (and the number 1), bit you can’t see why the test failed.

You could split up the Verify – use two verify calls to help pinpoint where it has failed:

[Test]
public void WhenCreatingAnOrderSaveTheCustomerDetails_SplitVerify()
{
  const int orderCreatedByPersonId = 1;

  var customerServiceMock = new Mock<ICustomerService>();

  var orderService = new OrderService(customerServiceMock.Object);
  orderService.CreateOrder(new Order { FirstName = "John", LastName = "Smith", OrderItems = new List<OrderItem>() }, orderCreatedByPersonId);

  customerServiceMock.Verify(x => x.Save(It.Is<Customer>(y => y.FirstName == "John"), orderCreatedByPersonId));
  customerServiceMock.Verify(x => x.Save(It.Is<Customer>(y => y.LastName == "Smith"), orderCreatedByPersonId));
}

And this is the error you’ll see. It is a lot better as you now know exactly which part of the verify call failed (i.e. the last name of the customer).

Moq.MockException :
Expected invocation on the mock at least once, but was never performed: x => x.Save(It.Is<Customer>(y => y.LastName == "Smith"), 1)
No setups configured.

Performed invocations:
ICustomerService.Save(Recommendations.Customer, 1)

Now let’s use callbacks instead t give you a much more obvious error message. In your arrange part of the test, you set up a callback to catch the data sent to the mocked dependency:

[Test]
public void WhenCreatingAnOrderSaveTheCustomerDetails_UsingCallbacks()
{
  const int orderCreatedByPersonId = 1;

  var customerServiceMock = new Mock<ICustomerService>();
  Customer actualCustomer = null;
  int actualSavedBy=0;
  customerServiceMock.Setup(x => x.Save(It.IsAny<Customer>(), It.IsAny<int>())).Callback<Customer,int>((customer, person) =>
                              {
                               actualCustomer = customer;
                               actualSavedBy = person;
                              }); //set up the callback to catch the parameters sent to Save()

  var orderService = new OrderService(customerServiceMock.Object);
  orderService.CreateOrder(new Order { FirstName = "John", LastName = "Smith", OrderItems = new List<OrderItem>()},orderCreatedByPersonId);

  actualSavedBy.Should().Be(orderCreatedByPersonId);
  actualCustomer.Should().NotBeNull();
  actualCustomer.FirstName.Should().Be("John");
  actualCustomer.LastName.Should().Be("Smith");
}

Now you’ll see a much nicer error message (from Fluent Assertions):

Expected string to be "Smith", but "John" is too short.

Posted in .NET, Moq, Test Driven Development | Tagged: , , | 1 Comment »

More TDD with wrapper classes

Posted by Kash Farooq on June 23, 2012

I have previously blogged about using wrapper classes to test the hard to test. In that post I made things easy for myself by using the parameterless constructor of the SmtpClient class.

I thought I’d revisit this area of testing, and try something different. This time I’ve used Moq rather than Rhino Mocks for starters. But I’m also going to pretend that SmtpClient does not have a parameterless constructor.  If a class you need to make testable does not have a parameterless constructor, it makes things a bit trickier:

public class SystemUnderTest
{
  public void MethodToBeTested()
  {
    var mailMessage = new MailMessage { Subject = "Hello", From = new MailAddress("Me@Me.com") };
    mailMessage.To.Add(new MailAddress("You@You.com"));
    var smtpClient = new SmtpClient("smtp.kashfarooq.com", 25);
    smtpClient.Send(mailMessage);
  }
}

A number of things in the above code need to be addressed and tested. The SMTP client is being instantiated in the method with the host and port being sent in via a the constructor, which makes things awkward to test. Apart from that complication, I’d like to make sure the correct host and port are being used. And I’d also like to make sure the correct details are being set in the MailMessage object.

First, we need an interface so we can mock the Send method. This matches the SmtpClient.Send method exactly:

public interface ISmtpClient
{
  void Send(MailMessage mailMessage);
}

We also need a wrapper class that will wrap SmtpClient and the constructor we are planning to use:

public class SmtpClientWrapper : SmtpClient, ISmtpClient
{
  public SmtpClientWrapper(string host, int port) : base(host, port)  { }
}

The above wrapper class inherits the interface defined above and the class we are trying to make testable: SmtpClient. And as it derives from SmtpClient, it automatically implements ISmtpClient.Send(MailMessage).

Next, we’ll create a suitable constructor for our SystemUnderTest class so that we can inject in some mocks. Because the MethodToBeTested creates the SmtpClient object, I’m going to use the “Using a Func instead of a Factory” trick:

private readonly Func<string, int, ISmtpClient> createSmtpClient;

public SystemUnderTest(Func<string, int, ISmtpClient> createSmtpClient)
{
  this.createSmtpClient = createSmtpClient;
}

public SystemUnderTest() : this((host,port) => new SmtpClientWrapper(host, port)) {}

So, what’s going on here? I have created a Func that will take a string and int (the host and port) and return an ISmtpClient. From my test I’ll use the first constructor. The production code will use the second constructor. In both cases, the Func supplied is stored in createSmtpClient – and this will be called from MethodToBeTested to actually create the SmtpClient.

I’m now in full control of all the dependencies. I can catch the MailMessage parameter sent to the Send method, and the host and port name sent to the createSmtpClient Func, which ultimately gets sent to to the SmtpClient(string host, int port) constructor.

And here is the test that creates a mock ISmtpClient and a Func that returns it, and also catches the parameters sent to it so the appropriate asserts can be done:

[Test]
public void CorrectEmailSentViaTheCorrectSmtpHost()
{
  string actualHostName=string.Empty;
  int actualPort=0;
  MailMessage actualMailMessage = null;

  var mockSmtpClient = new Mock<ISmtpClient>();
  mockSmtpClient
     .Setup(x => x.Send(It.IsAny<MailMessage>()))
     .Callback((MailMessage message) => actualMailMessage = message); //Catch the MailMessage sent to the Send method

  //Func to return an ISmtpClient and catch data sent to it
  Func<string, int, ISmtpClient> createSmtpClient = (host, port) =>
      {
         actualHostName = host; //catch the hostname used
         actualPort = port; //catch the port used
         return mockSmtpClient.Object; //return mocked SmtpClient
  };

  //Call system under test
  var sut = new SystemUnderTest(createSmtpClient);
  sut.MethodToBeTested();

  //Asserts
  actualHostName.Should().Be("smtp.kashfarooq.com");
  actualPort.Should().Be(25);
  actualMailMessage.Subject.Should().Be("Hello");
  actualMailMessage.From.Address.Should().Be("Me@Me.com");
  actualMailMessage.To[0].Address.Should().Be("You@You.com");
}

[Incidentally, I’m using the excellent FluentAssertions in my asserts.]

Posted in .NET, Moq, Test Driven Development | Tagged: , , , | Leave a Comment »

Checking what was sent to a mock, readability of test code and readability of assert messages

Posted by Kash Farooq on August 7, 2009

There are several ways to determine what was sent to your mock object.
In this blog post I’ll look at using Rhino Mocks and Moq to test the same piece of code and check that the correct data was sent to a dependency. I’ll then also look at not bothering with a Mocking Framework, and just using a Fake instead.

If the method being called on the mock receives a simple type, it is easy to check that the correct data was sent to the mock. For example, with Rhino Mocks:

dependency.AssertWasCalled(m=>m.MyMethod(5));

However, things aren’t as simple if MyMethod receives a complex type.

For the examples below, here is the code under test. I have a dependency that receives a complex type:

//A complex type
public class PersonDetail {
   public string Name { get; set; }
   public string Address { get; set; }
}

//The dependency
public interface IPersonDetailsRepository {
   void StorePersonDetails(PersonDetail personDetail);
}

public class SystemUnderTest
{
    private readonly IPersonDetailsRepository repository;
    public SystemUnderTest(IPersonDetailsRepository repository) {
        this.repository = repository;
    }
}

public void CreatePerson(string name, string address) {
   //intentional bug (address and name the wrong way around) so that we can check the test failure messages
   repository.StorePersonDetails(new PersonDetail {Name = address, Address = name});
}

Rhino Mocks Matches syntax

With Rhino Mocks, one way to check the parameter sent to StorePersonDetails is to use the Matches syntax.

[Test]
public void CheckPersonDetailsAreSaved_RhinoMocks_ArgsMatches()
{
    const string personAddress = "London";
    const string personName = "John Smith";

    var repository = MockRepository.GenerateStub<IPersonDetailsRepository>();
    new SystemUnderTest(repository).CreatePerson(personName, personAddress);

    repository.AssertWasCalled(x => x.StorePersonDetails
                                     (Arg<PersonDetail>.Matches(person => person.Name == personName)));

    //Error:
    //Rhino.Mocks.Exceptions.ExpectationViolationException:
    //IPersonDetailsRepository.StorePersonDetails(y => (y.Name = "John Smith")); Expected #1, Actual #0.
}

So, we caught the bug. However, I’d argue that it is not at all clear why the test failed. You’d have to look at the code under test. You cannot work out what went wrong by just looking at the error message. Is the error message telling us the dependency was not called at all, or that the argument sent was incorrect?

Rhino Mocks GetArgumentsForCallsMadeOn

The next Rhino Mocks method I’ll look at is one that I’ve discussed before. I think GetArgumentsForCallsMadeOn gives you a much clearer way to understand why your test failed:

[Test]
public void CheckPersonDetailsAreSaved_RhinoMocks_GetArgumentsForCallsMadeOn() {
    const string personAddress = "London";
    const string personName = "John Smith";

    var repository = MockRepository.GenerateStub<IPersonDetailsRepository>();
    new SystemUnderTest(repository).CreatePerson(personName,personAddress);

    var objectSentToRepository = (PersonDetail)repository
                                                  .GetArgumentsForCallsMadeOn
                                                       (r => r.StorePersonDetails(null))[0][0];
    Assert.That(objectSentToRepository.Name,Is.EqualTo(personName));

    //Error
    //NUnit.Framework.AssertionException:   Expected string length 10 but was 6. Strings differ at index 0.
    //Expected: "John Smith"
    //But was:  "London"
}

The error message you see in your test runner is clear – you know exactly what the bug in the code is. Much clearer than using the Matches syntax. However, you need an explicit cast and you are tying the test to the implementation in terms of parameter order of the dependency (see the caution at the bottom of my post about GetArgumentsForCallsMadeOn).

Moq

With Moq you also get an unclear assert error message:

[Test]
public void CheckPersonDetailsAreSaved_Moq() {
    const string personAddress = "London";
    const string personName = "John Smith";
    var repository = new Mock<IPersonDetailsRepository>();

    new SystemUnderTest(repository.Object).CreatePerson(personName, personAddress);

    //Both these give the same error seen below.
    repository.Verify(r=>r.StorePersonDetails(Match<PersonDetail>.Create(person => person.Name == personName)));
    repository.Verify(r=>r.StorePersonDetails(It.Is<PersonDetail>(x=>x.Name==personName)));

   //Error:
   //Moq.MockException:
   //Invocation was not performed on the mock:
   //x => x.StorePersonDetails(Match`1.Create(x1 => (x1.Name = "John Smith")))
}

Again, is the error message telling us the dependency was not called at all?

Note: you can also use callbacks to get a cleared test failure message. See: Using Moq callbacks to check complex arguments sent to a dependency.

Fakes

There is another way. If your dependency interface is small, why not use a Fake object? – i.e. don’t use a Mocking Framework at all:

private const string personAddress = "London";
private const string personName = "John Smith";

private class FakeRepository : IPersonDetailsRepository {
    public PersonDetail CollectedPersonDetails;
    public void StorePersonDetails(PersonDetail personDetail) {
        CollectedPersonDetails = personDetail;
    }
}

[Test]
public void CheckPersonDetailsAreSaved_Moq() {
    var fakeRepository = new FakeRepository();
    new SystemUnderTest(fakeRepository).CreatePerson(personName, personAddress);

    Assert.That(fakeRepository.CollectedPersonDetails.Name, Is.EqualTo(personName));

    //Error:
    //NUnit.Framework.AssertionException:   Expected string length 10 but was 6. Strings differ at index 0.
    //Expected: "John Smith"
    //But was:  "London"
}

Using a fake, we have a simple, readable test and when there is an assert failure, it is obvious what the bug is.

Posted in Moq, Rhino Mocks, Test Driven Development | Tagged: , , | 1 Comment »

Recursive Mocks: Comparing Moq to Rhino Mocks

Posted by Kash Farooq on July 28, 2009

Here is the simple ASP.NET MVC code I want to test.
In a test, I need to mock the HttpContext so that it returns an identity that I control.

public ContentResult ReturnUserName() {
   return Content(User.Identity.Name);
}

And here is the test code using the released binaries of Rhino Mocks 3.5:

[Test]
public void ContentContainingUserNameReturned_RhinoMock() {
   var mockContext = MockRepository.GenerateStub<ControllerContext>();
   var mockHttpContext = MockRepository.GenerateStub<HttpContextBase>();
   mockContext.HttpContext = mockHttpContext;
   var identity = new GenericIdentity("user");
   mockHttpContext.User = new GenericPrincipal(identity,null);

   var controller = new HomeController {ControllerContext = mockContext};
   ContentResult content = controller.ReturnUserName();

   Assert.That(content.Content, Is.EqualTo("user"));
}

That’s a fair amount of mocking to test a one line method.

Here is the test using Moq:

[Test]
public void ContentContainingUserNameReturned_Moq() {
   var mockContext = new Mock<ControllerContext>();
   mockContext
     .SetupGet(x => x.HttpContext.User.Identity.Name)
     .Returns("user");

   var controller = new HomeController {ControllerContext = mockContext.Object};
   ContentResult content = controller.ReturnUserName();

   Assert.That(content.Content, Is.EqualTo("user"));
}

Far more concise.

The feature that allows Moq to do this is called Recursive Mocks.
You could argue that if you need to do this in your code then you must be breaking the Law Of Demeter. Sometimes, as with HttpContext, you don’t have a choice. Ayende argues you are breaking this law, but has introduced Recursive Mocking in Rhino Mocks, along with guidance. You’ll have to download the code and build you own binaries to use it though.

Posted in Moq, Rhino Mocks, Test Driven Development | Tagged: , , , , | Leave a Comment »