It is a summary for myself. Describes how to create a Java unit test using the following library. --JUnit (Testing Framework) --Mockito (mock creation framework) --PowerMock (Mockito's extension framework)
I used Gradle to download the necessary files (JUnit, Mockito, PowerMock). The contents of the configuration file are as follows.
build.gradle
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:2.+"
testCompile 'org.powermock:powermock-module-junit4:2.0.0-RC.4'
testCompile 'org.powermock:powermock-api-mockito2:2.0.0-RC.4'
}
This is the class to be tested. Consider using JUnit, Mockito, and PowerMock for this class.
Samole.java
public class Sample {
private Sub sub;
public Sample() {}
public Sample(Sub sub) {
this.sub = sub;
}
public String pubGet() {
return "pubGet";
}
public String pubGet(String suffix) {
return pubGet() + suffix;
}
public String pubGetSubValue() {
return sub.getValue();
}
public String pubGetStaticValue() {
return Static.getValue();
}
private String priGet() {
return "priGet";
}
private String priGet(String suffix) {
return priGet() + suffix;
}
public static class Sub {
private String value;
public Sub(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public static class Static {
public static String getValue() {
return "Static value";
}
}
}
When using only JUnit.
SampleTest.java
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.Method;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
public class SampleTest {
private Sample instance;
@Before
public void init() {
this.instance = new Sample();
}
@Test
public void pubGet() {
//Public method testing
String actual = instance.pubGet();
assertThat(actual, is("pubGet"));
}
@Test
public void priGet() throws Exception {
//Private method test (no arguments)
Method method = Sample.class.getDeclaredMethod("priGet");
method.setAccessible(true);
String actual = (String) method.invoke(instance);
assertThat(actual, is("priGet"));
}
@Test
public void priGet_withArg() throws Exception {
//Private method test (with arguments)
Method method = Sample.class.getDeclaredMethod("priGet", String.class);
method.setAccessible(true);
String actual = (String) method.invoke(instance, "Suffix");
assertThat(actual, is("priGetSuffix"));
}
@Test
public void pubGetSubValue() {
Sample instance = new Sample(new Sample.Sub("test"));
String actual = instance.pubGetSubValue();
assertThat(actual, is("test"));
}
}
When Mockito is added. You can rewrite the contents of the method using a mock.
SampleForMockitoTest.java
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SampleForMockitoTest {
@Mock
private Sample mock;
@Spy
private Sample spy;
@Before
public void init() {
// @Initialize the mock object of the Mock annotation
MockitoAnnotations.initMocks(this);
}
@Test
public void pubGetSubValue() {
//When not using a mock
Sample instance = new Sample(new Sample.Sub("test"));
String actual = instance.pubGetSubValue();
assertThat(actual, is("test"));
}
@Test
public void pubGetSubValue_withMockito() {
//Returns the value of the stub when using a mock
Sample.Sub mock = mock(Sample.Sub.class);
when(mock.getValue()).thenReturn("mock value");
Sample instance = new Sample(mock);
String actual = instance.pubGetSubValue();
assertThat(actual, is("mock value"));
}
@Test
public void pubGetSubValue_withMockitoMock() {
// mock()Will be the default value (null) if stub is not implemented
String actual1 = mock.pubGet();
assertThat(actual1, is(nullValue()));
// mock()Returns the value of a stub when implementing a stub
when(mock.pubGet()).thenReturn("mock value");
String actual2 = mock.pubGet();
assertThat(actual2, is("mock value"));
}
@Test
public void pubGetSubValue_withMockitoSpy() {
// spy()Returns the actual value without implementing a stub
String actual1 = spy.pubGet();
assertThat(actual1, is("pubGet"));
// spy()Returns the value of a stub when implementing a stub
when(spy.pubGet()).thenReturn("mock value");
String actual2 = spy.pubGet();
assertThat(actual2, is("mock value"));
}
@Test
public void pubGetSubValue_withMockitoAnswer() {
// mock()Returns the value of a stub when implementing a stub
//Answer allows you to use method arguments for stubs
when(mock.pubGet(anyString())).thenAnswer(invocation -> {
String arg1 = (String) invocation.getArguments()[0];
return "mock value " + arg1;
});
String actual = mock.pubGet("suffix");
assertThat(actual, is("mock value suffix"));
}
}
When PowerMock is added.
You can rewrite the contents of the static
method.
SamleForPowerMockTest.java
import org.junit.Before;
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;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Sample.Static.class})
public class SamleForPowerMockTest {
private Sample instance;
@Before
public void init() {
instance = new Sample();
}
@Test
public void pubGetWithStatic() {
//Test the value of a static method
String actual = instance.pubGetStaticValue();
assertThat(actual, is("Static value"));
}
@Test
public void pubGetWithStatic_withPowerMock() {
// mockStatic()Static method returns stub value in
PowerMockito.mockStatic(Sample.Static.class);
//If you want the original behavior other than the desired method, use PowerMockito instead.spy()use
// PowerMockito.spy(Sample.Static.class);
PowerMockito.when(Sample.Static.getValue()).thenReturn("PowerMockito value");
String actual = instance.pubGetStaticValue();
assertThat(actual, is("PowerMockito value"));
}
}
PowerMock allows for powerful rewriting. However, if you rely too much on PowerMock, you lose sight of its original purpose (extensible implementation). I also felt the danger of being a test that only gained coverage, so it seems better to think about where to use it.
I referred to Use of Mockito and PowerMock properly.
Recommended Posts