Are you looking for a solution to your unit tests modifying data? Perhaps your unit tests are so slow that none of your teammates bother running them? You need mock objects.
The following items will be covered to help you write better tests:
Mocking is one of the most important factors in writing better unit tests. It drastically minimizes a test’s execution time and gives you an upper hand in validating complex logic without disk, database or service dependencies.
Mocks are more than the default-valued objects known as stubs. Mocks act as collaborators and are subject to behavioral modification. These collaborators will help you achieve your desired unit-testing goal for a given system and a controlled set of inputs. This is achieved by having the mock object stand in for the real object and returning data you have specified.
To get a complete overview of mocks, an informative article named “Mocks aren’t stubs” by Martin Fowler is a must read.
After you are finished, it’s time to give you a good grasp of mocking with a real world example.
I am going to implement part of a banking system. This includes the transfer of funds between two different currency accounts using the currency converter service.
To begin, I have created an ICurrencyService interface:
This service interface will be injected to an AccountsService class that is responsible for the transfer funds operation. Once the source and destination account objects are passed to the operation, it will then withdraw from source, convert the currency based on current rate, and finally deposit the converted amount to the target account. There will be a check for available balance, authorization, approval, etc. in more complex scenarios, but they are out of scope for this article.
AccountService : IAccountService
.currencyService = currencyService;
TransferFunds(Account from, Account to,
conversionRate = currencyService.GetConversionRate(from.Currency, to.Currency);
convertedAmount = amount * conversionRate;
The goal is to validate or assert the transfer funds operation between two accounts. Therefore, this is the system under test (SUT), and the currency service is the collaborator which will be mocked. I am using JustMock for this purpose, but the core concept is the same with other mocking tools.
First I will create the mock of the ICurrenyService interface:
ICurrencyService currencyService = Mock.Create<ICurrencyService>();
From the account service implementation, I can see that GetCurrencyService is being called to retrieve the conversation rate. The next step is to set an expected return value for it.
Mock.Arrange(() => currencyService.GetConversionRate(
Mock.Arrange is the entry-point for setting expected behavior for a given mock. This line is self-explanatory, but I did use one extra option: MustBeCalled. This ensures that if currencyService.GetConversationRate is not called with the above criteria, then it will fail the test.
Since I have finished setting the behavior, I will then create an instance of the AccountService class followed by the source and destination Account classes.
var accountService =
var canadianAccount =
var britishAccount =
Next, I will add some money into the GBP account:
Then transfer it to my Canadian account:
accountService.TransferFunds(britishAccount, canadianAccount, 100);
Once the transfer is complete, I need to make sure the operations happened as expected. I will first assert the balance of the two accounts:
Then I will assert the mock to verify whether the required GetConversationRate method is called as expected:
You may have noticed that there were three easy steps involved with the unit test. This is part of a well-known pattern called Arrange – Act – Assert or AAA. JustMock’s syntax is implemented to strictly follow the AAA pattern to give you a well-structured flow, even in the most complex scenarios.
In this post, I described how mocking will help you. I then built an example project and test to illustrate how to proceed. Mocking helps you write clean unit tests, and it enables you to focus on the test logic by isolating external factors. With mocking, unit testing is no longer a chore.
Mehfuz Hossain works as the Technical Advisor in DevTools Division . He is passionate playing around with the latest bits. He has been a Microsoft MVP, author of OS projects like LinqExtender and LINQ to flickr and most recently lighter (nodejs + mongo blogging engine). Prior to working at Telerik , Mehfuz worked as a core member in many high volume web applications including Pageflakes that is acquired by Live Universe in 2008. He is a frequent blogger and was also a contributor and site developer at dotnetslackers.com.
Copyright © 2017, Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
Progress, Telerik, and certain product names used herein are trademarks or registered trademarks of Progress Software Corporation and/or one of its subsidiaries or affiliates in the U.S. and/or other countries. See Trademarks or appropriate markings.