Hey, we Swiss are proud of our products! Have you ever owned a real Swiss Watch like this nice Rolex shown in the first picture? Or did you ever enjoy the delicious taste of Swiss chocolate? What about the quality of the famous Swiss Army knife? Didn’t we invent Ricola, or did we?
Well, there are some bad guys there who try to falsify our quality products. They sell mocks to the customers for very low prices. You might enjoy your holidays in say Singapore, Kenia or Thailand, to name just a few. All of a sudden you are confronted with a “nice” guy who wants to sell you Rolex watches or handbags from Gucci for a very very low price. You as a tourist cannot resist. “Finally I get a quality product for … nothing” you might think.
But buying mocks hurts or destroys the business of many Swiss company.
Thanks God we have our customs! They protect our businesses and stop all people who want to import mocks.
MOCKS ARE BAD !!!
Hell, wait a moment – what the sh… are you talking about? This is a developer’s blog. What do I care about falsified goods. I want to learn some new patterns, practices and techniques.
Ok, ok, I got you. So let’s start with some developer focused stuff. Let’s talk about stubbing and mocking in test driven development (TDD).
When doing test driven development (TDD) you sooner than later get into the situation where you have a system under test (SUT) which has dependencies, that is the SUT collaborates with other objects. View from the standpoint of the SUT the dependencies are part of it’s environment. During a unit test the developer has to simulate the environment of the SUT. Many people seem to get rather confused when having to deal with those (external) dependencies of the SUT and trying to simulate those dependencies. There are many terms floating around which all seem to describe the same thing. But there are subtle differences. Stubs, mocks, fakes or test doubles are the most common terms heard in discussions around unit-testing. In this post I want to discuss, what stubs and especially what mocks are and how they help me to simulate the environment of a SUT.
A method stub or simply stub is a piece of code used to stand for some other programming functionality. A stub may simulate the behavior of existing code or be a temporary substitute for yet-to-be-developed code. Stubs provide canned answers to calls made during the (unit-) test.
Mocks are simulated objects that mimic the behavior of real objects in a controlled way. In contradiction to a stub a mock insists on verification. Its method implementations contain assertions of their own. This means that a true mock, in this sense, will examine the context of each call—perhaps checking the order in which its methods are called, perhaps performing tests on the data passed into the method calls as arguments.
Using mock objects allows developers to focus their tests on the behavior of the system under test (SUT) without worrying about its dependencies. For example, testing a complex algorithm based on multiple objects being in particular states can be clearly expressed using mock objects in place of real objects.
Instrumenting a Mock
To be able to verify behavior a mock object has to be instrumented. What does that mean “…to instrument a mock…”? Please imagine being a pilot. You are sitting in the cockpit of a nice airplane, e.g. a Mig 29 as shown in the picture at the left. In front of you and all around you you have various gauges and displays. These gauges are also called instruments and they show you the status and behavior of various parts of the plane.
The said instruments are not needed for the aircraft to work properly but they are there for you as a pilot to find out whether every thing is working as expected.
As an example your expectation might be that the flaps are closed after take-off. To verify your expectation you have an dedicated instrument in the cockpit which shows you whether the flaps are closed or not closed.
When a developer is instrumenting an object (e.g. a mock) she does something similar with this object as explained in the above sample of the aircraft. She will add some gauges to the object which she can then use to verify whether an expected behavior has been diagnosed or some state has changed. The gauges that she is adding to the object is extra code [which is not an essential part of the object's main concern].
Consider an example where a mail sender sub-system has been mocked. The mock object implements a method Send(string to, string subject, string body) to match the one present in the real mail sender class. If the mock object now exposes a boolean property MailSent, which is not present in the real class, then a unit test code can now easily verify expectations that a mail has or has not been sent by the system under test (SUT). In our case the Send method of the mock object would just set the property MailSent to true.
To summarize: the implementation of additional properties and/or logic in the mock object, which are not present in the real class, is called instrumentation. The developer adds some code to the mock just for verification of expectations.
Let our SUT be a account service. With this service we can open a new account for a given customer. In the context of opening such a new account the account object shall be added to an account repository. The repository is an external dependency of the SUT. Since on one hand we want to test the SUT in isolation and on the other hand either the repository is not yet implemented or if it exists it should not be used since it is e.g. coupled to a specific database configuration, we have to mock the repository.
In our test we want to verify a specific behavior of the SUT. Thus we cannot use a stub object but have to use a mock object.
The SUT receives the mock object via constructor injection (see: Dependency Injection – DI)
Manual implementation of the mock object
In the above code we prepare the unit-test in the Arrange block. In the Act block the call to the method of the SUT whose behavior we want to test is executed.
In this test the Assert block which is the third block in the Arrange-Act-Assert syntax (also called AAA syntax) is missing on purpose. We have no verification of expectations so far.
From the test code above we can immediately deduce that we need a repository of type MockAccountRepository which implements an interface IAccountRepository. The interface as we need it for the test is defined below
Since the account service only accesses the repository via the interface IAccountRepository and as such is not tied to a specific implementation of the repository we can provide an alternative implementation of the said interface (this is then what we now call a “mock object“) and pass an instance of this alternative repository implementation to our SUT. This implementation we adapt to our specific needs. The needs are defined by the unit test which shall use this mock object. It is important to remember that this mock object is ONLY needed for testing purposes. Thus we are completely free how we design the implementation of the mock object.
In the code snippet above a possible implementation of the mock repository is given. In this implementation a public boolean field MethodAddCalled was introduced. This field is part of the instrumentation of the mock object and allows us to verify during the unit test whether the method Add of the repository has been called or not.
The code below shows the complete unit-test including the Assert block.
In the Assert block we use the instrumentation of the mock object to verify the behavior of the SUT. The mock object has been configured such as that it sets the field MethodAddCalled to true whenever the method Add is called. Note that we have to cast the mock repository to access the field MethodAddCalled since this field is not part of the interface and only part of the implementation.
To make our unit test run we implement the minimal amount of code needed
The problem here is, that the implementation of the OpenNewAccount method makes no sense. We just pass null to the repository and the test passes. So we have to improve the test and at the same time extend the instrumentation of our repository mock. We can add a property LastAccountAdded to the mock and use this property in the test code to verify our expectations that e.g. an non-null value is passed to the repository. The modified repository mock is shown below
and the unit test can be extended by the following assert statement
Now the code of the OpenNewAccount method has to be modified to make the unit test run again. The following would work
A mock providing a canned answer
The creation of a new account instance is a potentially complex operation. So it would make sense to create and use a factory for this purpose. The account service will use the account factory and thus the factory is a new dependency of the SUT (the service). We will have to mock the factory. The interface we need for the factory is
and the modified account service
We have to implement the factory mock in such a way that it can return pre-configured account objects when its method Create is called. A possible implementation is given below
I have instrumented the mock with a field AccountToReturnOnCreate. This field can be used by the test code to provide a prepared account object which in turn will be returned to the caller of the method Create.
Now I have to update the unit test again to integrate all those changes
Note that in the arrange block I prepare an account instance, I create a mock of the account factory and I assign the prepared account object to the AccountToReturnOnCreate field of the mock. The assert statement verifies that the account object returned by the factory is indeed passed to the repository.
Using a mocking framework
Writing mocks and/or stubs is a repetitive and boring labor. Any developer should avoid to do repetitive code whenever possible. The solution in this case is to use one of the available mocking frameworks. Given an interface such a mocking framework automatically creates a mock or stub for it. We can the use the framework to instrument the mock and to assert our expectations. In the following I’ll have a look at two different mocking frameworks. Both of them are rather well known. The first is Rhino.Mocks (version 3.5) and the second one Moq (version 3.0). Depending on which framework you use you either have to reference the assembly Rhino.Mocks.dll or Moq.dll in the project which contains the unit tests.
Create a mock
Let’s first create a mock for the interface IAccountRepository:
This is the code needed when working with Rhino.Mocks
and for Moq
The mocking framework creates a mock and instruments it such as that certain expectations can be verified. Among these expectations are verifying that a specific call has been made to one of the methods of the mock.
And now let’s show how we can verify our expectation that a certain method call has indeed been made on the mock. Again let’s first show the code needed for Rhino.Mocks
and for Moq
Note that the sole difference between the two frameworks is the name of the method used for verification. Rhino.Mocks uses AssertWasCalled and Moq uses Verify.
In the above verification we have included that a call to the method Add was made and that the given instance (account) of type Account has been passed as an argument to that call. Note that the verification fails if another instance (or null) is passed to the method Add of the mock.
If we want to relax our expectations a little bit and just test whether
- the call has been made regardless the parameter or
- a non-null value is passed
then the syntax is for Rhino.Mocks
and for Moq
Setup or configure a mock
The mocking framework also allows us to setup a mock object, that is we can tell it to return prepared data on a specific method call. If we take as an example the account factory, we can mock it an tell the mock to return a previously prepared account instance if its method Create is called. Here is the code snippet for Rhino.Mocks
and here for Moq
Again the only difference between the two frameworks is the naming used for their respective setup methods. Rhino.Mocks uses Stub and Moq uses Setup. The operation that is expected to return a result (in this case an account object) has to be passed as a lambda function in both frameworks.
When implementing (with TDD) a new class this class is called system under test (SUT). Most of the time a SUT has one to many dependencies, that is other classes/objects or resources it depends on. Those dependencies can be called the environment of the SUT. To develop and test the SUT in isolation we have to simulate the environment. Instead of the real dependencies we provide mocks (or stubs) to our SUT. A mock or a stub is a placeholder for a real object and can provide canned answers to the SUT. In contradiction to a stub a mock is also instrumented such as that the test code can verify expectations regarding the behavior of the SUT. Mocks or stubs can and often are implemented “by hand”. But this is a boring and repetitive task and the instrumentation of a mock can very quickly become complex. Luckily there are many mocking frameworks available which can automatically create mocks (and stubs) for us. Most of these frameworks are very flexible and allow us to verify any (reasonable) expectation and to further setup or configure the mocks according to the needs of a specific (unit-) test.