Unit Testing with Mockito/PowerMockito
Mockito is an open-source Mocking framework in Java. The features it provides for unit-testing is important.
It has simplified test case writing for developers. While Mockito can help with test case writing, there are certain things it cannot do viz:. mocking or testing private, final or static methods. That is where, PowerMockito comes to the rescue. PowerMockito is capable of testing private, final or static methods as it makes use of Java Reflection API.
The best way to get started with Mockito, or PowerMockito is to find its Maven dependency and add it to the project.
Here are the dependencies we need to add:
Maven Dependencies –
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>1.6.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>1.6.2</version> <scope>test</scope> </dependency>
Allows shorthand creation of objects required for testing.
- Minimizes repetitive mock creation code
- Makes the test class more readable
Few exmaples –
@RunWith – Indicates which framework APIs to refer to
For PowerMockito – @RunWith(PowerMockRunner.class)
For Mockito – @RunWith(MockitoJUnitRunner.class )
@PrepareForTest -Used only in case of PowerMockito. This informs PowerMockito which classes to prepare with Java Reflection API for testing.
@Test – Defines the method as Junit tes case
@Mock – Instead of mocking the object in traditional way. This annotation directly mocks the declared object
@Spy – To Spy on existing instance
@Before– For initialization purpose i.e. initializing the object before use
Generic syntax for mocking –
- For mocking the method calls –
Above mocking will return message when printMessage method gets called with any string.
- In case of static methods, use like below –
Here, getProperty(..) is a static method present inside class- PropertiesReader
So static mock class before mocking its static method
This will mock the new object creation
i.e. when new instance of type – ClassWithFinalMethods is being generated , our mocked object – ‘mockObject’ will get returned instead of actual/real new object.
Whitebox.setInternalState(mockVmReplication1, ID_PROPERTY, REPLICATION_ID1);
This will set the state/value of member variables inside mocked object
In above example, ID_PROPERTY of mockVmReplication1 will get set with value = REPLICATION_ID1
Call real methods to test using mocked objects –
Real methods can be called from Junit test cases in 2 ways-
- Using doCallRealMethod() –
This will call actual method – methodUnderTest() when called using mocked object – mockObject.methodUndertest();
- Using actual object creation –
ClassUnderMock obj = new ClassUnderMock(); obj.methodUnderTest();
|doCallRealMethod dont create real objects||Actual object creation will create real objects which is not recommended in mocking|
|Real object creation avoids setting of member variables present inside constructor||Need to set state of member variables which are getting set in constructor|
Assert and Verify –
Assert and Verify are used for checking/verifying the results of mocking.
Assert class has multiple static methods which can be used for testing the results of mocking. Below are the few examples for the same:-
Assert.assertEquals – Fails when expected and actual value are not equal
Assert.assertNotNull – Fails when actual value is NULL
Assert.assertNotEquals – Fails when expected and actual value are equal
Assert.assertTrue – Fails when actual value is false
Assert.assertFalse – Fails when actual value is true
- To ensure that the code satisfies all of the required functionality, under all (or most of) the input combinations/values.
- To ensure that I can change the implementation, and rely on JUnit test cases to tell me that all my functionality is still satisfied.
This will verify whether the methdUndertest() is called only 1s on mockedObject
If not then execution fails with below trace-
“Wanted 2 times but was 1 time”
[Tweet “Unit Testing with Mockito/PowerMockito ~ via @CalsoftInc”]