mock clock

What Is A Mock?

mock clock

 

Unit tests should not involve network I/O—our tests would be slow and subject to network connectivity. Instead of using collaborating classes that provide the network connectivity, unit tests should use fake stand-ins that help us get through the test and detect whether we would have made remote calls correctly. 

These fake collaborators, often in aggregate called fakes or mocks, come in different flavours. We have previously covered DummiesStubs and Spies. Today we’ll take a look at Mocks

Spies detect and record how calls to the reals collaborators would have been made so that this information can be recalled and asserted against in a unit test. Mocks are like spies bar one aspect: The assertion step is done inside the mock, not in the unit test, as with a spy.

Let’s take a look at how our previous unit test example would look using a mock rather than a spy:

[Fact]
public void Given_New_Customer_When_Call_Register_Then_Save_Customer()
{
   var mockRepository = new MockCustomerRepository();
   var useCase = new RegisterNewCustomerUseCase(mockRepository );

   await useCase.Register(FredFlintstoneRego);

   repository.VerifySaveCustomerCall(FredFlintstone);
}

The definition for MockCustomerRepository:

public class MockCustomerRepository : ICustomerRepository
{
   private bool WasSaveCustomerCalled;
   private Customer PassedInCustomer;

        public async Task SaveCustomer(Customer customer)
        {
            WasSaveCustomerCalled = true;
            PassedInCustomer = customer;
        }

        public void VerifySaveCustomerCall(Customer customer)
        {
            WasSaveCustomerCalled.Should().BeTrue();
            PassedInCustomer.Should().BeEquivalentTo(customer);
        }
    }

So the difference between mocks and spies is that mocks assert internally, while spies simply record the call details, and the unit test performs the assertions.    

I prefer the simplicity of writing my own manual mocks. I hardly ever need to use an isolation or mocking framework, like Moq. However, for the sake of completeness, I’ll demonstrate how we write the unit test with Moq:

[Fact]
public void Given_New_Customer_When_Call_Register_Then_Save_Customer()
{
   var mockRepository = new Mock<ICustomerRepository>();
   var useCase = new RegisterNewCustomerUseCase(mockRepository.Object);

   await useCase.Register(FredFlintstoneRego);

   mockRepository.Verify(x => x.SaveCustomer(FredFlintstone));
}
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply