Tuesday, February 28, 2012

Mocks & Spies


Mocks & Spies

We all know how JUnit is important for making sure that our code is doing what it is supposed to be doing. Mocks are integral part of JUnit. When you test a class you usually want to isolate that class from the rest of the world and concentrate on that class. To do that you need to use Mocks. Mocks let you mimic the components that your tested class deals with, without really needing to make sure they are really there. You can ‘teach’ a mock to act in ways you need and by doing so test your class to make sure it actually doing the right stuff based on the input data and the mocks behavior.
There are a few Mock frameworks in Java. In this post I will describe the way to work with PowerMock. PowerMock lets you work with mocks and spies.

Mock

When we deal with mocks, we can either mock an instance for its non-static public/protected/private methods or mock the static methods of a class.

Mocking an instance

Mocks are created when you need to completely replace an instance.
Guidelines:
1.     There’s no instance of the mocked class, rather there is an instance of a proxy mock that represents it.
2.     The mock can mock a concrete class or an interface.
3.     When a method that is not mocked is called:
a.  If the called method returns a value, then the returned value will be the return type’s default value.
b.  In case of a ‘void’ method nothing is done.
4.     To mock a method you should do the following
The preferred syntax is:
a.   To mock a method with a return value: PowerMockito.doReturn(value).when(mock).method(arguments);
b.   To mock a void method
PowerMockito.doNothing().when(mock).method(arguments);
Example:



Spy

Spying (partial mock) after an instance  

Spy is created when you need to have a ‘partial mock’. That means when you have a real instance and you need to call at least one of its real methods and to mock other(s).
1.     A Spy, unlike mock, works on a real instance.
2.     By default a method that is called will activate the real method.
3.     To mock a method you must do the following:
a.   To mock a method with a return value: PowerMockito.doReturn(value).when(spy).method(arguments);
b.   To mock a void method
PowerMockito.doNothing().when(spy).method(arguments);

Note that you first need to declare the return value and then the method, otherwise the method will be activated.





Spy: Mocking Private Methods

Mocking private methods is done a bit differently and for that we need to do the following:
1.     Add the PrepareForTest annotation with the class/classes that we need to mock their private method(s), for example:

2.     Use the following syntax, for example:

Note, you will need to add ‘throws Exception’ to your test declaration.

3.   Verification
Example 1: 
Verify that the method “privateMethod” was called for ‘spy’





Example 2: 
Verify that the method “privateMethodOther” was never called for ‘spy’


Mock: Mocking Static Methods

Mocking private methods is done a bit differently and for that we need to do the following:
1.     Add the PrepareForTest annotation with the class/classes that we need to mock their static methods, for example:





2.     Use the following syntax, for example:



Note, when you need to mock static methods, you are mocking ALL the static methods of the class.

3.     Mocking a static method:

4.     Verification, you can only check that static methods were called once like that:





Note that verification on static methods is usually not needed.


Spy: Mocking Static Methods

Mocking private methods is done a bit differently and for that we need to do the following:

Add the PrepareForTest annotation with the class/classes that we need to mock their static methods, for example:




      Use the following syntax, for example:




Note, when you need to mock static methods, you are mocking ALL the static methods of the class.

3   Mocking a static method:


     Calls to a non-mocked static method will activate that method.

     Verification, you can only check that static methods were called once like that:





Note that verification on static methods is usually not needed.

Examples

Suppose we have the following ‘TestedClass’ that we wish to test. The class has public and private methods (static and non-static):





 











Test declaration







Mock- Mocking a public non-static method

By default the mock would return null since that is the default value for the returned type ‘String’. We override that by ‘teaching’ the mock to return ‘testPublic’:










Mock - Mocking a private non-static method




Mock - Mocking a public static method

Spy – mocking a public non-static method

Note:
1.   The spy works on a real instance of ‘TestedClass’.
2.   You need to declare the ‘doReturn’ first, otherwise the real method ‘publicMethod’ will be activated.
3.   When a non-mocked method is called (‘publicMethodOther’) the real method is invoked.









Spy – Mocking a private non-static method

Note
1.   The syntax is the same for mocks and spies.
2.   The syntax that is using the method’s name.
3.   The test might throw exception.



Spy – Mocking static methods

We spy over the class ‘TestedClass’ since we want to mock only ‘testPublicStatic’ but not the other static method ‘publicStaticMethod1’:




Spy – mocking private static method

In this case we have a spy, ‘spy’, that spies on an instance of ‘TestedClass’ and we also spy on the static methods of ‘TestedClass’.  We use spy for the static methods since we want only to mock the private static method ‘privateStaticMethod’ while other static methods should behave as usual.



Spy – combination

A spy, mock on all static methods and mocking a private method of the spy:


No comments:

Post a Comment