Using Powermock it is possible to mock a new instance to avoid unnecessary depth to your unit test. This is relatively unusual in an IoC environment (inversion of control eg spring) because you'd inject the PropertyLoader and therefore mocking would be easy. However, particularly in legacy code this can be found.
If a class has this method you many not want to traverse into the PropertyLoader.
public class MyClass {
/**
* Method to enrich the object with a property applicable for today.
*
* @param myObj The object to be enriched
*/
public void enrichWithProperties(MyObject myObj) {
final PropertyLoader propertyLoader = new PropertyLoader();
myObj.setProperty(propertyLoader.getTodaysProperty());
}
}
It could be that new PropertyLoader() has a whole series of dependencies that you don't want to end up mocking as this will make the unit test really unclear. Instead you can use Powermock to return a mocked PropertyLoader instance to greatly simply things.
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Test class for the .....
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MyClassTest {
/** The class under test. */
private MyClass classUnderTest = new MyClass();
@Test
public void testEnrichWithProperties() {
// Arrange
final String todaysValue = "todaysValue";
final MyObject myObj = new MyObject();
final PropertyLoader mockedPropertyLoader = mock(PropertyLoader.class);
whenNew(PropertyLoader.class).withAnyArguments().thenReturn(mockedPropertyLoader);
when(mockedPropertyLoader.getTodaysProperty()).thenReturn(todaysValue);
// Act
classUnderTest.enrichWithProperties(myObj);
// Assert
assertEquals(todaysValue, myObj.getProperty());
}
}
Note: Unlike the mocking statics, you have to PrepareForTest the class which instantiates the mocked class not the mocked class itself. So above MyClass is prepared not PropertyLoader.
Showing posts with label Mockito. Show all posts
Showing posts with label Mockito. Show all posts
Thursday, 9 March 2017
Friday, 11 November 2016
Mocking Static Classes with Powermock
I always forget how to do this and have to look it up every time so here is a quick example for future reference!
- Annotate the class with @RunWith(PowerMockRunner.class)
- Annotate the class with @PrepareForTest(<class-to-mock>.class)
- Mock the static in @Before or in @Test PowerMockito.mockStatic(<class-to-mock>.class)
- Set expectations with when(<class-to-mock.class>.something()).thenReturn(something_else)
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* An example of using powermock to mock a static class.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest(StringUtils.class)
public class ExampleTest {
/**
* Test blank when mocked to return that an empty string isn't blank!
*/
@Test
public void testBlankMocked()
{
// Arrange
PowerMockito.mockStatic(StringUtils.class);
when(StringUtils.isBlank("")).thenReturn(false);
// Act
final boolean blank = StringUtils.isBlank("");
// Assert
assertFalse(blank);
}
/**
* Test blank using the standard non-mocked behaviour.
*/
@Test
public void testBlankNormal()
{
// Act
final boolean blank = StringUtils.isBlank("");
// Assert
assertTrue(blank);
}
}
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
- Annotate the class with @RunWith(PowerMockRunner.class)
- Annotate the class with @PrepareForTest(<class-to-mock>.class)
- Mock the static in @Before or in @Test PowerMockito.mockStatic(<class-to-mock>.class)
- Set expectations with when(<class-to-mock.class>.something()).thenReturn(something_else)
Example
This is a simple example which mocks StringUtils (apache commons-lang3). This shows that the StringUtils.isBlank() method can be mocked to return different values.
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* An example of using powermock to mock a static class.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest(StringUtils.class)
public class ExampleTest {
/**
* Test blank when mocked to return that an empty string isn't blank!
*/
@Test
public void testBlankMocked()
{
// Arrange
PowerMockito.mockStatic(StringUtils.class);
when(StringUtils.isBlank("")).thenReturn(false);
// Act
final boolean blank = StringUtils.isBlank("");
// Assert
assertFalse(blank);
}
/**
* Test blank using the standard non-mocked behaviour.
*/
@Test
public void testBlankNormal()
{
// Act
final boolean blank = StringUtils.isBlank("");
// Assert
assertTrue(blank);
}
}
Maven Dependencies
The powermock dependencies used for this test are,<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
Subscribe to:
Posts (Atom)