每次@InjectMocks调用都不考虑 PowerMock 静态方法模拟



我想编写一些使用Junit 4.12,Mockito 1.9.5和PowerMock 1.6.1的单元测试。该类具有@mock注释的一些字段,以及@InjectMocks注释的一些字段。用@InjectMocks注释的属性在某个时候达到了一个包含某些静态方法调用的父构造器,应使用PowerMock对其进行模拟。问题是第一个测试无缝起作用,而第二个测试似乎根本没有模拟静态方法。

@RunWith(PowerMockRunner.class)
@PrepareForTest({ StaticClass.class })
public class TestClass {
  @Mock
  private SomeClass attribute1;
  @InjectMocks
  private SomeOtherClass attribute2;
  @BeforeClass
  public static void setUp() {
    PowerMockito.mockStatic(StaticClass.class);
 when(StaticClass.staticMethod(any(), any()).thenReturn(new SomeConcreteClass());
  }
  @Test
  public void test1() {
    assertEquals(attribute2.method1(), value1);
  }
  @Test
  public void test2() {
    assertEquals(attribute2.method2(), value2);
  }
}
public class SomeOtherClass {
  private SomeClass attribute;
  public SomeOtherClass() {
    SomeConcreteClass value = StaticClass.staticMethod(argument1, argument2);
    value.someOtherMethod();
  }
}

如前所述,第一个测试通过,staticclass.staticmethod((被PowerMock所预期的。第二个测试不会通过,当调用某些hotershod的值时,它会在线上抛出NullPoInterException(因为value = null,因为staticclass.staticmethod不再被PowerMock嘲笑(。

如(使用PowerMock在每次测试后重置(PowerMock在每个测试之前重置模拟。

由于某种原因,它第一次起作用 - 存在该问题的未解决的错误报告(https://github.com/powermock/powermock/issues/398(。


它的设计可以说是不好的,但是做您想做的事情的一种方法是:
而不是依靠注释手动设置模拟。

private SomeClass attribute;
private SomeOtherClass testClass;
@Before
public void setUp() {
    PowerMockito.mockStatic(StaticClass.class);
    Mockito.when(StaticClass.staticMethod(anyString())).thenReturn(new SomeConcreteClass());
    attribute = Mockito.mock(SomeClass.class);      
    testClass = new SomeOtherClass();
    // assign mock manually
    testClass.attribute = attribute;
}

首选的方法是使用SomeOtherClass的构造函数提供attribute您必须从外部设置值。
如果无法访问attribute实例,则可能被迫使用反射。


清洁剂的方法是重构SomeOtherClass的构造函数,以不使用内部静态方法。而是将SomeConcreteClass作为参数传递给构造函数是要走的方式。

有些人甚至说您不应该在构造函数内有任何逻辑。

相关内容

  • 没有找到相关文章

最新更新