以编程方式替换PowerMock的@PrepareForTest?

问题描述 投票:19回答:2

我正在使用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并将@PrepareForTest注释添加到MockLibraryOne类中,但是我将在其他单元测试中依赖于MockLibraryOne,因此继承不是一般解决方案。

有没有一种方法可以在PowerMock下以编程方式准备类进行测试,而不是使用@PrepareForTest注释?例如,类似以下内容:

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类?

编辑:模拟策略可能是一个解决方案:https://code.google.com/p/powermock/wiki/MockPolicies

编辑:模拟策略与PowerMockRunner一起工作,但没有(似乎)与PowerMockRule(我有时因类加载器问题而需要)。

unit-testing junit powermock
2个回答
0
投票

为什么你甚至想模拟静态方法?为什么不将这些静态方法包装在可以用mockito模拟的类中呢?

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

然后你可以创建一个你的FooWraper模拟器。根本不需要使用Powermock ......


0
投票

也许你正在寻找一个mock policy

© www.soinside.com 2019 - 2024. All rights reserved.