10 minute read

This series on Mock frameworks takes you through Rhino Mocks, Moq and NSubstitute frameworks to implement mock and unit testing in your application.  This series of posts is full of examples, code and illustrations to make it easier to follow.  If you have not followed this series through, I would recommend you reading following articles

  1. Understanding Mock and frameworks – Part 1 of N – Understanding the need of TDD, Mock and getting your application Unit Test ready
  2. Understanding Mock and frameworks – Part 2 of N – Understanding Mock Stages & Frameworks – Rhino Mocks, NSubstitute and Moq

In Part 1, we understood how to refactor our application so that it can be Unit tested with Mock frameworks and in Part 2, we understood 3 stages of Mocking – Arrange, Act and Assert with an example.  Now as understood in Part 2 ‘Arrange’ is the stage where implementation in all the three framework differs.  So in this post, we will focus on ‘Arrange’ and explore various types of mocking.

Mocking Method Calls

In the examples below, we will mock a method call GetCount of the service so that it returns value 10.  We will clear the controller and then check if GetCount method was actually called.  If this example was called without using Mock frameworks, the outputs would have been different. Please note that in the below examples all the mock methods are applied on the service; however, you can apply them on the controller as well.

Using Rhino Mocks

Rhino Mocks uses methods AssertWasCalled and AssertWasNotCalled to check if the ‘actual’ method was invoked.

  1. [TestMethod]
  2. publicvoid T03_TestMethodCall()
  3. {
  4.     var service = MockRepository.GenerateMock<IService>();
  5.     var controller = newController(service); // injection
  6.     service.Stub(x => x.GetCount()).Return(10);
  7.     controller.Clear();
  8.     service.AssertWasNotCalled(x => x.GetCount());
  9.     service.AssertWasCalled(x => x.Clear());
  10. }

Using NSubstitute

NSubstitute uses DidNotReceive and Received methods to check if the ‘actual’ methods got a call or not.  There are multiple similar methods available such as DidNotReceiveWithAnyArgs, ClearReceivedCalls, and ReceivedCalls.  Each of these functions can be used to manipulate or check the call stack.

  1. [TestMethod]
  2. publicvoid T03_TestMethodCall()
  3. {
  4.     var service = Substitute.For<IService>();
  5.     var controller = newController(service);
  6.     service.GetCount().Returns(10);
  7.     controller.Clear();
  8.     service.DidNotReceive().GetCount();
  9.     service.Received().Clear();
  10. }

Using Moq

Moq standardizes the verification of method calls with a single method Verify. The Verify method has many overloads allowing to even evaluate an expression.

  1. [TestMethod]
  2. publicvoid T03_TestMethodCall()
  3. {
  4.     var service = newMock<IService>();
  5.     var controller = newController(service.Object);
  6.     service.Setup(x => x.GetCount()).Returns(0);
  7.     controller.Clear();
  8.     service.Verify(x => x.GetCount(), Times.Never());
  9.     service.Verify(x => x.Clear());
  10. }

Mocking Method Calls and their Output

The next example focuses on a more real time scenario, where we will mock a method that takes input parameters and returns an output parameter.  The service will be mocked and we will test the functionality of our controller.

So going back to Part 2 of our series, if a NULL input is passed to Add method of the controller it returns back false.  For any non-NULL input, it gives a call to Add method of the service and returns back the value returned by the service.  So we will pass two different types of objects to the controller and return 2 different outputs based on our mock.  When we pass ServiceObject with name ‘m1’ we will mock it to return value ‘false’ while ServiceObject with name ‘m2’ should return value ‘true’

Using Rhino Mocks

What’s important to focus at his moment is that we altered the behavior and hence used the method Stub on the mocked service and then later we defined the expected result by the method Returns.

  1. [TestMethod]
  2. publicvoid T04_TestConditions()
  3. {
  4.     var service = MockRepository.GenerateMock<IService>();
  5.     var controller = newController(service); // injection
  6.     ServiceObject oneThatReturnsFalse = newServiceObject("m1", Guid.NewGuid());
  7.     ServiceObject oneThatReturnsTrue = newServiceObject("m2", Guid.NewGuid());
  8.     service.Stub(x => x.Add(oneThatReturnsFalse)).Return(false);
  9.     service.Stub(x => x.Add(oneThatReturnsTrue)).Return(true);
  10.     Assert.AreEqual(false, controller.Add(oneThatReturnsFalse));
  11.     Assert.AreEqual(true, controller.Add(oneThatReturnsTrue));
  12. }

Using NSubstitute

NSubstitute does not require any method like Stub. When you are defining any method on the mocked service object, it automatically assumes that the framework has to alter the behavior of the method.  Just like Rhino Mocks, method Returns defines the expected mocked output of that method.

  1. [TestMethod]
  2. publicvoid T04_TestConditions()
  3. {
  4.     var service = Substitute.For<IService>();
  5.     var controller = newController(service);
  6.     ServiceObject oneThatReturnsFalse = newServiceObject("m1", Guid.NewGuid());
  7.     ServiceObject oneThatReturnsTrue = newServiceObject("m2", Guid.NewGuid());
  8.     service.Add(oneThatReturnsFalse).Returns(false);
  9.     service.Add(oneThatReturnsTrue).Returns(true);
  10.     Assert.AreEqual(false, controller.Add(oneThatReturnsFalse));
  11.     Assert.AreEqual(true, controller.Add(oneThatReturnsTrue));
  12. }

Using Moq

Moq like Rhino Mocks requires a special method call Setup and then followed by another method call to Returns method

  1. [TestMethod]
  2. publicvoid T04_TestConditions()
  3. {
  4.     var service = newMock<IService>();
  5.     var controller = newController(service.Object);
  6.     ServiceObject oneThatReturnsFalse = newServiceObject("m1", Guid.NewGuid());
  7.     ServiceObject oneThatReturnsTrue = newServiceObject("m2", Guid.NewGuid());
  8.     service.Setup(x => x.Add(oneThatReturnsFalse)).Returns(false);
  9.     service.Setup(x => x.Add(oneThatReturnsTrue)).Returns(true);
  10.     Assert.AreEqual(false, controller.Add(oneThatReturnsFalse));
  11.     Assert.AreEqual(true, controller.Add(oneThatReturnsTrue));
  12. }

Strict Mock vs Normal Mock

 

Strict Mock creates brittle tests.   A strict mock is a mock that will throw an exception if you try to use any method that has not explicitly been set up to be used.  A dynamic (or loose, normal) mock will not throw an exception if you try to use a method that is not set up, it will simply return a default value from the method and keep going.  The concept can be applied to any mocking framework that supports these 2 types of mocking.

Let’s see an example with Rhino Mocks.  We will alter our controller class to add a method Find that invokes two methods of our IService interface

  1. publicpartialclassController
  2. {
  3.     publicServiceObject Find(string name)
  4.     {
  5.         if (string.IsNullOrEmpty(name))
  6.             thrownewArgumentNullException(name);
  7.         if (_service.GetCount() > 0)
  8.         {
  9.             /* Can have more business logic here */
  10.             return _service.GetObject(name);
  11.         }
  12.         else
  13.         {
  14.             returnnull;
  15.         }
  16.     }
  17. }

Now with a Strict Mock on the method GetObject and no mock on method GetCount, we should expect an exception to be thrown.  However, when using a dynamic/loose mock, GetCount will return its default value which is Zero (0 ) and hence Find Method will return NULL

  1. [TestMethod]
  2. publicvoid T10_TestStrictMock()
  3. {
  4.     // data
  5.     string name = "PuneetG";
  6.     ServiceObject output = newServiceObject(name, Guid.NewGuid());
  7.     // arrange
  8.     var service = MockRepository.GenerateMock<IService>();
  9.     var controller = newController(service);
  10.     var strictService = MockRepository.GenerateStrictMock<IService>();
  11.     var controllerForStrictMock = newController(strictService);
  12.     // act
  13.     service.Stub(x => x.GetObject(name)).Return(output);
  14.     // assert
  15.     Assert.AreEqual(null, controller.Find(name));
  16.     Assert.AreEqual(output, controllerForStrictMock.Find(name)); // exception expected
  17. }

When you execute this Test, the first assert will pass and the second assert will throw an exception.  Overall the test will fail.

The Code for Download

Understanding RhinoMocks, NSubstitute, Moq by Puneet Ghanshani

Hope this helps. In the next post, we will explore how to mock Exceptions and Events