Building my own tech
Now Reading
Use mocks to make unit testing painless.

Use mocks to make unit testing painless.

by NishantAugust 6, 2015

In my last post I talked about how to use Test Driven Development (TDD) to drive the development of your software projects and ensure the individual units are well tested.

You will often write unit tests for methods which rely on other classes to do their work. The obvious choice is to initialise and pass through new instances of the classes (concrete implementations) which it is dependent on.

However, that approach is ill-advised when the required class is big and complex as you don’t want to be running intensive code statements unless they are the things you are testing. Classes like these should have their own unit tests where the complex logic is tested for correctness.

Remember, you should only be testing what you’re supposed to be testing and not the things it’s using to do its work. Sounds obvious but it’s easy to forget.

Moreover, if you want to verify that your method under test behaves a certain way when certain situations arise, you can use mock objects to simulate the occurrence of the such conditions.

If the class you are testing doesn’t get constructed with the objects it relies on already, the idea of mocks will make you think about implementing some sort of dependency injection and control the behaviour when writing unit tests using mocks.

Example

You are using TDD to implement a new piece of code that should output a suitable error message when a certain type of exception is encountered.

You start off by writing a unit test:

public void DoSomething_OnArrayEmptyException_ReturnsHelpfulMessage()
{
// Arrange
var mockService = new Mock(Service);
mockService.Setup(x => x.DoComplexTask(int[]).Throws(ArrayEmptyException)();
ClassUnderTest = new ServiceUser(mockService.Object);
var expectedMessage = "Array was empty."
// Act
var result = ClassUnderTest.DoSomething(new int[]);
// Assert
Assert.AreEqual(expectedMessage, result);
}

In our unit test, we first set up a mock instance of the Service object and set it up to throw an ArrayEmptyException regardless of the input. The ClassUnderTest (being your ServiceUser class) is constructed with this mock instance of the Service object.

Your ServiceUser class will then look like:

public class ServiceUser
{
private IService _service;
public class ServiceUser(IService service)
{
_service = service;
}
public string DoSomething(int[] array)
{
string result;
try
{
result = _service.DoComplexTask(array)
}
catch(ArrayEmptyException)
{
result = "Array was empty."
}
return result;
}
}

If you look at the constructor of the ServiceUser class, you will see that it accepts an implementation of the IService interface and assigns it to a field which is used within this class.

It is important that you create interfaces for your concrete implementations of objects so that they can be mocked easily. (You can think of a mock object as an implementation of some interface with its functionality being mocked.)

When the unit test runs the DoSomething method inside the ServiceUser class the mock object will throw an ArrayEmptyException when the DoComplexTask method is called.

The method under test will catch the exception and change the value of the result variable and return it, thus implementing the functionality we intended.

By using a mock object, we don’t need to know exactly what an underlying object does and avoid unnecessary computations by defining its behaviour through its mock.

Final comments

In this post I covered how you can go about writing unit tests quickly and easily by using mocks. Using mocks allows us to control the behaviour of a object that our method/class under test requires in order to verify that our it works as expected when certain situations occur. By using mocks, we can also avoid the need for writing large amount of code to construct the required objects and use processing power to do work that isn’t being tested in our unit test.

If you would like to incorporate mocking into your unit testing then check out the following libraries/frameworks:

.NET:

Top 20 NuGet packages for mocking

My favourites are Moq and NSubstitute.

Java:

Mockito

jMock

EasyMock

Image used under creative commons

This article was brought to you by Netshock. Netshock is your technology blog, providing technology news, guides and insight

What's your reaction?
Love It
0%
Interested
0%
Meh...
0%
What?
0%
Hate It
0%
Sad
0%
About The Author
Nishant

Software developer with skills in .NET and Java, believes in good coding practices and agile development.

I am interested in using technology to solve problems and I enjoy working on my own software projects.

I like experimenting with and writing about new ways to develop software products. I also like to watch football and cricket, and I play when I can.