TL;DR
- 外部クラスには
@Runwith(Enclosed.class)
のみ - 内部クラスには下記をつけてやる
@RunWith(PowerMockRunner.class)
@PrepareForTest({テスト対象クラス})
-
@PowerMockRunnerDelegate(Parameterized.class)
-
@PowerMockRunnerDelegate(JUnit4.class)
は不要
-
やりたかったこと
- staticイニシャライザ実行される処理のテストが書きたかった
- テスト内にパラメタライズドテストと1回だけ流したいテストが混在していた
- とは言え一つのクラスに対するテストコードが複数箇所に分散するのは気持ち悪い
調べてみた
- staticに割り込むテストはMockito + PowerMockで出来る
- パラメタライズドテストは
@RunWith(Theories.class)
か@RunWith(Parameterized.class)
を使えば出来る-
Parameterized
だとパラメータ毎にアサーションしてくれたのでこっちを採用
-
-
@RunWith(Enclosed.class)
を使えば一つのクラスに複数のテストクラスをまとめられる
ライブラリ構成
- junit: 4.12
- mockito-core: 1.10.19
- powermock-core: 1.7.3
- powermock-module-junit4: 1.7.3
- powermock-api-mockito: 1.7.3
検証コード
テスト対象
public class StaticClass {
public static String MESSAGE;
static {
int i = new Random().nextInt();
if (0 <= i && i <= 10) {
MESSAGE = "Parameter is inside of range, 0 to 10.";
} else {
MESSAGE = "Nmm...?";
method();
}
}
private static void method() {
// to do any action
}
}
テスト
@RunWith(Enclosed.class)
public class StaticClassTest {
@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticClass.class})
@PowerMockRunnerDelegate(Parameterized.class)
public static class ParameterizeTest {
@Parameterized.Parameter
public Integer parameter;
@Parameterized.Parameters(name = "parameter is {0}")
public static Object[][] parameterSupplier() {
return new Object[][]{
{0},
{1},
{2},
{3},
{4},
{5},
{6},
{7},
{8},
{9},
{10}
};
}
@Test
public void test() throws Exception {
// given
Random random = PowerMockito.mock(Random.class);
PowerMockito.whenNew(Random.class).withNoArguments().thenReturn(random);
PowerMockito.when(random.nextInt()).thenReturn(parameter);
// expect
assertEquals("Parameter is inside of range, 0 to 10.",
Whitebox.getInternalState(StaticClass.class, "MESSAGE"));
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticClass.class})
public static class NormalTest {
@Test
public void test() throws Exception {
// given
Random random = PowerMockito.mock(Random.class);
PowerMockito.whenNew(Random.class).withNoArguments().thenReturn(random);
PowerMockito.when(random.nextInt()).thenReturn(99);
// expect
assertEquals("Nmm...?",
Whitebox.getInternalState(StaticClass.class, "MESSAGE"));
}
}
}
参考
http://tomoyamkung.net/2013/08/28/java-junit4-enclosed/
https://stackoverflow.com/questions/28027445/powermock-access-private-members