2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

パラメタライズドテストと普通のテストを抱き合わせにしたクラスでPowerMockを使いたい

Last updated at Posted at 2017-10-19

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

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?