With PowerMock, you can mock the Enum class and write test code in JUnit.
| version | |
|---|---|
| Java | 8 |
| JUnit | 4.12 |
| Mockito | 2.23 |
| PowerMock | 2.0.2 |
public enum SampleEnum {
ELEM1("val1"),
ELEM2("val2");
private String val;
private SampleEnum(String val) {
this.val = val;
}
public String getVal() {
return this.val;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(SampleEnum.class)
public class SampleEnumTest {
@Test
public void test() throws Exception {
//Expected value
String expected_elem1 = "test";
String expected_elem2 = "val2";
//Mock an Enum
SampleEnum mocked = Mockito.mock(SampleEnum.class);
//Set the return value in the method and stub
Mockito.when(mocked.getVal()).thenReturn(expected_elem1);
//If not stubbed
// Mockito.when(mocked.getVal()).thenCallRealMethod();
//Set a mocked object in the element of Enum
Whitebox.setInternalState(SampleEnum.class, "ELEM1", mocked);
//Run
String actual_elem1 = SampleEnum.ELEM1.getVal(); // "test"Returns
String actual_elem2 = SampleEnum.ELEM2.getVal(); // "val2"Returns
//Check the result
assertEquals(expected_elem1, actual_elem1);
assertEquals(expected_elem2, actual_elem2);
}
}
In fact, the Enum mocking itself doesn't use the PowerMock library.
It can be mocked with the Mockito library, like Mockito.mock (SampleEnum.class).
(PowerMockito.mock, PowerMockito.when can also be used instead of Mockito.)
The point is to specify PowerMockRunnner.class in @Runwith and describe the Enum class you want to mock in @PrepareForTest.
After that, you can set the return value with thenReturn (), or call the actual method with thenCallRealMethod () without stubbing.
If you try to comment out @Runwith and @PrepareForTest and execute it, the following error log will be output.
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class jp.co.sample_powermock.enumtest.SampleEnum
Mockito cannot mock/spy because :
- final class
The JUnit4 test runner doesn't seem to support mocking the Enum class.
Each Enum constant can be thought of as an instance of an Enum. By injecting a mocked Enum object into each of these instances, Enum mocking is established.
The sample code uses the PowerMock library Whitebox.setInternalState () to inject a mock object into the Enum element "ELEM1".
As a result, SampleEnum.ELEM1 behaves as the set mock object, and SampleEnum.ELEM2 behaves as it is.
You can set mock objects in java.lang.reflect without using Whitebox, but I think using Whitebox keeps your code simpler.
Recommended Posts