在需要测试的类上使用powermock模拟构造函数

时间:2019-06-17 07:15:47

标签: java junit mockito powermock powermockito

我能够在我要测试的类中使用powermock模拟构造函数调用。当我在@PrepareForTest中添加要测试的类时,此方法有效。但是,一旦我将类添加到此处,即使测试用例通过,覆盖率插件中的覆盖率也将显示为0。

当我从@PrepareForTest中删除类时,当然会开始显示其他测试用例的覆盖范围,但是必须模拟构造函数调用的测试用例失败。不知道该怎么办。

Class A
{
   MyObject o;
   A(){
     //some other code
     o = new MyObject();
     //some other code
   }

  public void process(){
    //some code

}

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
Class TestA{

  @Test
  public void test1()
  {
    MyObject mocked = Mockito.mock(MyObject.class);
 PowerMockito.whenNew(MyObject.class).withNoArguments().thenReturn(mocked);
  A a = new A();
  a.process();
  //Assert as per test case

 }

}

在coverage工具中,coverage显示为0,但是,单元测试通过了,我在调试模式下检查它是否覆盖了A类的所有语句。

2 个答案:

答案 0 :(得分:1)

  

在coverage工具中,coverage显示为0,但是,单元测试通过了,我在调试模式下检查它是否覆盖了A类的所有语句。

覆盖工具依赖于操纵执行的字节码。

当您模拟静态/新建时,PowerMock也是如此。

这可以迅速导致各种问题。对于JaCoCo,似乎offline instrumentation周围有解决方案。我还记得在哪里:另一个人回想起那段时间,最后放弃了,因为他也无法使用“离线检测”来工作。

对于任何其他框架,我必须重复旧的建议:考虑花费您的时间来学习如何编写易于测试的代码。因为如果这样做,则不需要使用PowerMock(ito)对其进行测试。

由于构造函数中的new()语句,您的代码很难测试。根本不要那样做。可以通过@InjectMocks使用依赖项注入,也可以使用仅测试的构造方法,该构造方法获取所需的对象。

长话短说:当您编写自己的新代码,并且认为需要PowerMock对其进行测试时,您就在做错事情。

答案 1 :(得分:0)

我认为您无需Powermock就可以做到。如果您在课程A上进行间谍活动并模拟吸气剂,您应该得到相同的结果,并且很可能覆盖了正确的范围:

@Test
public void test1(){
    MyObject mocked = Mockito.mock(MyObject.class);
    A spyA = Mockito.spy(new A());
    doReturn(mocked).when(spyA).getMyObject();
    ...
}