简体   繁体   English

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

[英]Mocking constructor using powermock on the class which needs to be tested

I am able to mock a constructor call using powermock from inside a class which I want to test. 我可以在要测试的类中使用powermock模拟构造函数调用。 This works when I add the class I want to test in @PrepareForTest. 当我在@PrepareForTest中添加要测试的类时,此方法有效。 But once I add my class there, even when the test cases pass, the coverage is being shown as 0 in the coverage plugin. 但是,一旦我将类添加到此处,即使测试用例通过,覆盖率插件中的覆盖率也将显示为0。

When I remove my class from @PrepareForTest , of course, coverage starts showing up for other test cases but the test case in which I have to mock constructor call fails. 当我从@PrepareForTest删除我的类时,当然,其他测试用例的覆盖率开始显示,但是必须模拟构造函数调用的测试用例失败。 Not sure what to do about this. 不知道该怎么办。

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

 }

}

In coverage tool, coverage shows as 0 however, unit test passes and I checked in debug mode that it was covering all the statements of class A. 在coverage工具中,coverage显示为0,但是,单元测试通过了,我在调试模式下检查它是否覆盖了A类的所有语句。

In coverage tool, coverage shows as 0 however, unit test passes and I checked in debug mode that it was covering all the statements of class A. 在coverage工具中,coverage显示为0,但是,单元测试通过了,我在调试模式下检查它是否覆盖了A类的所有语句。

Coverage tools rely on manipulating the executed byte code. 覆盖率工具依赖于操纵执行的字节码。

So does PowerMock, when you mock static/new. 当您模拟static / new时,PowerMock也是如此。

This can quickly lead to all sorts of problems. 这会很快导致各种问题。 For JaCoCo, there seems to be a solution around offline instrumentation . 对于JaCoCo,似乎有一种围绕离线仪表的解决方案。 Where, I also remember: some other person asked about that some time back, and in the end gave up, because he couldn't get "offline instrumentation" to work either. 我还记得在哪里:另一个人回想起那段时间,最后放弃了,因为他也无法使用“离线检测”来工作。

For any other framework, I have to repeat old advice: consider to invest your time to learn how to write easy-to-test code. 对于任何其他框架,我不得不重复旧的建议:考虑花费您的时间来学习如何编写易于测试的代码。 Because if you would do that, you would not need to use PowerMock(ito) in order to test it. 因为如果您这样做,则无需使用PowerMock(ito)对其进行测试。

Your code is hard-to-test because of that new() statement in the constructor. 由于构造函数中的new()语句,因此代码难以测试。 Simply don't do that. 根本不要那样做。 Either use dependency injection via @InjectMocks, or have a test-only constructor that takes the required object. 通过@InjectMocks使用依赖项注入,或者使用仅测试的构造函数来获取所需的对象。

Long story sort: when you write your own, new code, and you think you need PowerMock to test it, then you are doing something wrong. 长话短说:当您编写自己的新代码,并且认为需要PowerMock对其进行测试时,您就在做错事情。

I think you can do without Powermock here. 我认为您无需Powermock也可以。 If you Spy on class A and mock the getter you should end up with the same result and most likely have your coverage correct: 如果您间谍A类并模拟吸气剂,那么您应该得到相同的结果,并且很可能覆盖了正确的范围:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM