31

私は PowerMock を使用して、junit テストで静的メソッドをモックしています。通常は次のように実行されます。

@RunWith(PowerMockRunner.class)
@PrepareForTest({Foo.class,Bar.class})
public class SomeUnitTest {

  @Before
  public void setUpTest() {
    setUpFoo();
    setUpBar();
  }

  private void setUpFoo() {
    mockStatic(Foo.class);
    when(Foo.someStaticMethod()).thenReturn(1);
  }

  private void setUpBar() {
    mockStatic(Bar.class);
    when(Bar.someStaticMethod()).thenReturn(2);
  }

  @Test
  public void someTestCase() {
    ...
  }

}

これは問題なく動作しますが、@PrepareForTest注釈を指定すると、テスト API を柔軟にすることが妨げられていることがわかりました。

私がやりたいことは、次のようなものです。

public class MockLibraryOne {

  public static void setUpLibraryOne() {
    setUpFoo();
    setUpBar();
  }

  private static void setUpFoo() {
    mockStatic(Foo.class);
    when(Foo.someStaticMethod()).thenReturn(1);
  }

  private static void setUpBar() {
    mockStatic(Bar.class);
    when(Bar.someStaticMethod()).thenReturn(2);
  }

}

@RunWith(PowerMockRunner.class)
public class SomeUnitTest {

  @Before
  public void setUpTest() {
    MockLibraryOne.setUpLibraryOne();
  }

  @Test
  public void someTestCase() {
    ...
  }

}

ここで、単体テストは に依存していますが、依存するLibraryOneクラスがわからないため、注釈LibraryOneに追加するクラスがわかりません。@PrepareForTest

クラスにアノテーションをSomeUnitTest拡張MockLibraryOneして追加することはできますが、他の単体テスト以外にも依存するため、継承は一般的な解決策ではありません。@PrepareForTestMockLibraryOneMockLibraryOne

@PrepareForTest注釈を使用する代わりに、PowerMock でテストするクラスをプログラムで準備する方法はありますか? たとえば、次のようなものです。

public class MockLibraryOne {

  public static void setUpLibraryOne() {
    setUpFoo();
    setUpBar();
  }

  private static void setUpFoo() {
    prepareForTest(Foo.class);
    mockStatic(Foo.class);
    when(Foo.someStaticMethod()).thenReturn(1);
  }

  private static void setUpBar() {
    prepareForTest(Bar.class);
    mockStatic(Bar.class);
    when(Bar.someStaticMethod()).thenReturn(2);
  }

}

PowerMockRunner注釈を少し異なる方法で処理するといいと思い@PrepareForTestます。指定されたクラスごとに、そのクラス (およびその階層) をクラスのリストに追加してモックの準備をするだけでなく、そのクラスを調べて、@PrepareForTest同様に注釈があります:

@RunWith(PowerMockRunner.class)
@PrepareForTest({MockLibraryOne.class})
public class SomeUnitTest {
  ...
}

@PrepareForTest({Foo.class,Bar.class})
public class MockLibraryOne {
  ...
}

}

したがって、この@PrepareForTest注釈でSomeUnitTestは が見つかりMockLibraryOne、そこにある注釈はおよびも@PrepareForTestドラッグされます。Foo.classBar.class

したがって、おそらく、置換する独自のテスト ランナーを作成するPowerMockRunnerことが解決策になる可能性があります。

PowerMockAgentまたは、たとえばクラスを使用して、より簡単な解決策があるのでしょうか?

編集: モック ポリシーは 1 つの解決策かもしれません: https://code.google.com/p/powermock/wiki/MockPolicies

編集:モックポリシーは動作しますが、動作しPowerMockRunnerません(PowerMockRuleクラスローダーの問題のために必要になることがあります)。

4

4 に答える 4

0

おそらく、モック ポリシーをお探しですか?

于 2013-11-01T21:28:40.720 に答える
-1

なぜ静的メソッドをモックしたいのですか? それらの静的メソッドを、mockito でモックできるクラスにラップしてみませんか?

class FooWraper {
   void someMethod() {
     Foo.someStaticMethod()
   }
}

その後、FooWraper のモックを作成できます。Powermock を使用する必要はまったくありません...

于 2016-01-29T22:00:03.267 に答える