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