Kash Farooq's software development blog

.NET Developer

Posts Tagged ‘Rhino Mocks’

Rhino Mocks and AssertWasCalled MethodOptions

Posted by Kash Farooq on September 3, 2009

I always seem to struggle to find examples of how to use MethodOptions in Rhino Mocks, so here is some code.

Assume you have the following dependency:

public interface IDependency {
   void SomeMethod(int number);
   void SomeMethod(ComplexType complexType);
}

public class ComplexType {
   public string Name { get; set; }
}

And your system under test calls this dependency like this:

public class SystemUnderTest {
   private readonly IDependency dependency;
   public SystemUnderTest(IDependency dependency) {
      this.dependency = dependency;
   }

   public void DoSomething() {
       dependency.SomeMethod(9);
       dependency.SomeMethod(3);
   }

   public void DoSomethingElse() {
       dependency.SomeMethod(new ComplexType{Name = "London"});
   }
}

You can use MethodOptions to check that the dependency was called correctly.

First, let’s check that SomeMethod was called twice with integers greater than 1:

[Test]
public void EnsureDependencyCalledTwiceWithAnIntegerGreaterThanOne() {
  var dependency = MockRepository.GenerateStub<IDependency>();
  var systemUnderTest = new SystemUnderTest(dependency);
  systemUnderTest.DoSomething();

  dependency.AssertWasCalled(x => x.SomeMethod(0), 
                                                 options => 
                                                 {
                                                     options.Repeat.Twice();
                                                     options.Constraints(Is.GreaterThan(1));
                                                     options.Message("SomeMethod should have been called twice with integers greater than 1");
                                                 });
}

Next, let’s check that the correct ComplexType was sent to SomeMethod

[Test]
public void EnsureDependencyCalledWithCorrectComplexType() {
  var dependency = MockRepository.GenerateStub<IDependency>();

  var systemUnderTest = new SystemUnderTest(dependency);
  systemUnderTest.DoSomethingElse();

  Func<ComplexType, bool> checkArgs = arg => arg.Name == "London";
  //The above line can be written with an anonymous method instead:
  //Func<ComplexType, bool> checkArgs = delegate(ComplexType arg) { return arg.Name == "London"; };

  dependency.AssertWasCalled(x => x.SomeMethod(new ComplexType()), 
                                                        options => {
                                                           options.Callback(checkArgs);
                                                           options.Message("Name sent was not London");
                                                        });
}
Advertisements

Posted in Rhino Mocks, Test Driven Development | Tagged: , | 1 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 »

TDD with wrapper classes

Posted by Kash Farooq on January 12, 2009

Sometimes, during TDD, you come across a class that does not have an interface and therefore isn’t easy to test with Rhino Mocks. You’ll often find this is the case when you want to ensure that a class from the Base Class Library is being called correctly.
You can get around the problem using a wrapper class and an interface that describes the areas of the class you want to test.

For example, let’s say you have a method that uses System.Net.Mail.SmtpClient:

    public class SystemUnderTest {
        public void MethodUnderTest() {
            SmtpClient smtpClient=new SmtpClient();
            smtpClient.Port = 25;
            smtpClient.Host = "smtp.example.com";
            smtpClient.Send(new MailMessage{Subject = "Hello"});
        }
    }

SmtpClient is our external dependency. We want to test that the correct port and host has been set, and that Send is called with a MailMessage that has the subject “Hello”.

We start by creating an interface called ISmtpClient that includes the method and properties on SmtpClient that we want to test:

    public interface ISmtpClient {
        string Host { get; set; }
        int Port { get; set; }
        void Send(MailMessage mailMessage);
    }

We can now inject this into our system under test:

public class SystemUnderTest {      
   private readonly ISmtpClient smtpClient;

   public SystemUnderTest(ISmtpClient smtpClient) {
     this.smtpClient = smtpClient;
   }
        
   public void MethodUnderTest() {
      smtpClient.Port = 25;
      smtpClient.Host = "smtp.example.com";
      smtpClient.Send(new MailMessage{Subject = "Hello"});
   }
}

The test now becomes simple. Create a mock ISmtpClient, inject it into our system under test, and then assert that it was called correctly:

[Test]
public void MethodUnderTestSetsPortAndHostAndThenSendsMessage() {
	var mockRepository = new MockRepository();
	var smtpClient = mockRepository.DynamicMock<ISmtpClient>();

	mockRepository.ReplayAll();
	var systemUnderTest = new SystemUnderTest(smtpClient);
	systemUnderTest.MethodUnderTest();

	smtpClient.AssertWasCalled(x => x.Host = "smtp.example.com");
	smtpClient.AssertWasCalled(x => x.Port = 25);
	var mailMessage = (MailMessage)smtpClient.GetArgumentsForCallsMadeOn(x => x.Send(null))[0][0];
	Assert.AreEqual("Hello",mailMessage.Subject);
}

The final piece of the jigsaw is to wrap SmtpClient and implement ISmtpClient. The wrapper class will be used as the real implementation by the system under test:

public class SmtpClientWrapper : SmtpClient, ISmtpClient {}

Here is the final version of SystemUnderTest, using the wrapper class:

public class SystemUnderTest {
	private readonly ISmtpClient smtpClient;
	public SystemUnderTest() : this(new SmtpClientWrapper()) {}

	public SystemUnderTest(ISmtpClient smtpClient) {
		this.smtpClient = smtpClient;
	}

	public void MethodUnderTest() {
		smtpClient.Port = 25;
		smtpClient.Host = "smtp.example.com";
		smtpClient.Send(new MailMessage {Subject = "Hello"});
	}
}

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

Rhino Mocks and GetArgumentsForCallsMadeOn

Posted by Kash Farooq on January 10, 2009

Rhino Mocks includes a couple of ways to ensure your dependencies are called with the correct data. One is by using Rhino Mocks Matches syntax.

Another way is by using a Rhino Mocks extension method called GetArgumentsForCallsMadeOn. I think with this method you get clearer assert error messages.

Here is some sample code to show the usage:

Let’s start with a dependency that receives some data via a parameter:

public interface IDependency {
  int DoSomething(SomeComplexType someComplexType,
                        int someInteger);
}

public class SomeComplexType {
  public string stringData { get; set;}
}

Our system under test looks like this, receiving the dependency via Dependency Injection:

public class SystemUnderTest {
  private readonly IDependency dependency;
  public SystemUnderTest(IDependency dependency) {
     this.dependency = dependency;
  }

  public int MethodUnderTest(string data1, int data2) {
	var someComplexType1 = new SomeComplexType { stringData = string.Format("Sending {0}", data1) };
	var dataReturnedByCall1 = dependency.DoSomething(someComplexType1, 1111);

	var someComplexType2 = new SomeComplexType { stringData = string.Format("Sending {0}", data2) };
	var dataReturnedByCall2 = dependency.DoSomething(someComplexType2, 2222);

	return dataReturnedByCall1 + dataReturnedByCall2;
  } 
}

To check that DoSomething is called with the correct data, we use GetArgumentsForCallsMadeOn.

[Test]
public void EnsureDependencyIsCalledWithCorrectArguments() {

	//Arrange
	var mockRepository=new MockRepository();
	var dependency = mockRepository.DynamicMock<IDependency>();
	dependency.Expect(x => x.DoSomething(null, 0))
                        .IgnoreArguments()
                        .Return(7);
	dependency.Expect(x => x.DoSomething(null, 0))
                        .IgnoreArguments()
                        .Return(3);

	//Act
	mockRepository.ReplayAll();
	var systemUnderTest=new SystemUnderTest(dependency);
	var returned = systemUnderTest.MethodUnderTest("MyData",1234);

	//Assert
	Assert.AreEqual(10,returned);

	IList<object[]> argumentsSentToDoSomething = 
             dependency.GetArgumentsForCallsMadeOn(x => x.DoSomething(null, 0));
	var arg1Call1 = (SomeComplexType)argumentsSentToDoSomething[0][0];
	var arg2Call1 = (int)argumentsSentToDoSomething[0][1];
	var arg1Call2 = (SomeComplexType)argumentsSentToDoSomething[1][0];
	var arg2Call2 = (int)argumentsSentToDoSomething[1][1];
	Assert.AreEqual("Sending MyData", arg1Call1.stringData);
	Assert.AreEqual(1111, arg2Call1);
	Assert.AreEqual("Sending 1234", arg1Call2.stringData);
	Assert.AreEqual(2222, arg2Call2);
}

GetArgumentsForCallsMadeOn is used to get arguments sent to the dependency. GetArgumentsForCallsMadeOn returns a two dimensional array of objects so you will need to cast to get to the types you are expecting. The arguments sent to the first call to DoSomething are at position 0,0 and 0,1 of this array. For the second call to DoSomething, the arguments are at position 1,0 and 1,1.

Note that the data sent in the action to GetArgumentsForCallsMadeOn can be anything (I have sent null and 0 in the example above). Your dependency has already been called at this point and we are just telling Rhino Mocks which method you want the arguments for.

A word of caution

Credit to Matt for pointing this out to me.
Be aware that GetArgumentsForCallsMadeOn is not a strongly typed way of doing things. You are getting the data sent to the dependency in a “weak” way – i.e. by grabbing data by position out of a two dimensional array. If someone changes the order of the parameters in the dependency, there is a danger that the dependent class’ test will fail, even though the code under test is correct. This would highlight that you have a test that is deeply tied to the implementation and is hindering refactoring.

Posted in Rhino Mocks, Test Driven Development | Tagged: , | 4 Comments »

Mocking WCF Services with Rhino Mocks

Posted by Kash Farooq on November 29, 2008

With WCF self-hosting it is easy to substitute an external service dependency with a mock service.
If you have code that calls an external web service, and you want to create an integration test that ensures that the external web service is called with the correct data, you can combine WCF self-hosting and a mocking framework to replace the external web service.
First, let’s create a pretend external web service that has one method that receives a complex type.

namespace TheService
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        Acknowledgement SubmitOrder(Order order);
    }

    [DataContract]
    public class Order {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public IList OrderLines { get; set; }
    }

    [DataContract]
    public class OrderLine {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Description { get; set; }
    }
}

The system under test uses this web service:

namespace TheClient {
    public class Facade {
        public bool SubmitOrder() {
            var order=new Order();
            order.Id = 1;
            order.OrderLines=new List();
            order.OrderLines.Add(new OrderLine{Description = "OrderLine1",Id = 1});
            order.OrderLines.Add(new OrderLine{Description = "OrderLine2",Id = 2});
            Acknowledgement acknowledgement;
            using (var serviceClient=new ServiceClient()) {
                acknowledgement = serviceClient.SubmitOrder(order);
            }
            return acknowledgement.Success;
        }
    }
}

Now we can write an integration test that makes sure we call the service with two order lines. First I create a class that implements the service contract. The methods do not need to be implemented as we will use Rhino Mocks to mock the behaviour – however notice that I had to make the method virtual so that I can use PartialMock. Also note the InstanceContextMode. It needs to set to “single” so that a mock service object can be loaded by ServiceHost.

namespace IntegrationTests {
   [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class PartialMockService : IService {
        public virtual Acknowledgement SubmitOrder(Order order) {
            throw new NotImplementedException();
        }
    }
}

Now I can create the test. The mock needs to be set up in the TestFixtureSetup so that the service is running throughout all the tests.
The test sets up expectations on the service mock, and checks the arguments that were sent to the service method.

    [TestFixture]
    public class PartialMockTheService {
        private ServiceHost host;
        private MockRepository mockRepository;
        private PartialMockService serviceMock;

        [TestFixtureSetUp]
        public void TestFixtureSetUp() {
            mockRepository = new MockRepository();
            serviceMock = mockRepository.PartialMock<PartialMockService>();
            host = new ServiceHost(serviceMock);
            host.AddServiceEndpoint(typeof (IService), new BasicHttpBinding(), "http://localhost:8093/Service.svc");
            host.Open();
        }

        [Test]
        public void FacadeShouldCallTheWebserviceWithTwoOrderLines() {
            serviceMock.Expect(x => x.SubmitOrder(new Order()))
                            .IgnoreArguments()
                            .Return(new Acknowledgement {Success = true});
            mockRepository.ReplayAll();
            var facade = new Facade();

            Assert.IsTrue(facade.SubmitOrder());
            IList argumentsForCallsMadeOn = serviceMock
                              .GetArgumentsForCallsMadeOn(x => x.SubmitOrder(null));
            var order = (Order) argumentsForCallsMadeOn[0][0];
            Assert.AreEqual(2, order.OrderLines.Count);
        }
    }
}

The unit test app.config needs the same Service Model confiuration settings as the system under test, with the service location altererd so that it points to your mock rather than the real service.

<system.serviceModel>
        <client>
            <endpoint
                    address="http://localhost:8093/Service.svc"
                    binding="basicHttpBinding"
                    contract="TheServiceProxy.IService" />
      </client>
</system.serviceModel>

I tried to do the same test but with DynamicMock rather than PartialMock. If you can get this to work you save some code as you won’t need to create PartialMockService. However, I could not get this to work. I got the error:

The service class of type IServiceProxyc688097f68fa4881a2eac45ad09283ba both defines a ServiceContract and inherits a ServiceContract from type TheService.IService. Contract inheritance can only be used among interface types. If a class is marked with ServiceContractAttribute, it must be the only type in the hierarchy with ServiceContractAttribute.

Basically, it appears as though the ServiceContract attribute is on both interface and dynamically created concrete. I did some brief investigation and I don’t think the problem is inside Rhino Mocks – I think it is in Castle’s DymanicProxy code that Rhino Mocks uses.

Related Posts

Stubbing RESTful services with WCF

Posted in .NET, Rhino Mocks, Test Driven Development, WCF | Tagged: , , | 1 Comment »