Java 使用 PowerMockito.whenNew() 不会被嘲笑并调用原始方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25317804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using PowerMockito.whenNew() is not getting mocked and original method is called
提问by user3942446
I have a code somewhat like this below:
我有一个类似于下面的代码:
Class A {
public boolean myMethod(someargs) {
MyQueryClass query = new MyQueryClass();
Long id = query.getNextId();
// some more code
}
}
Class MyQueryClass {
....
public Long getNextId() {
//lot of DB code, execute some DB query
return id;
}
}
Now I'am writing a test for A.myMethod(someargs)
. I want to skip the real method query.getNextId()
and instead return a stub value. Basically, I want to mock MyQueryClass
.
现在我正在为A.myMethod(someargs)
. 我想跳过真正的方法query.getNextId()
,而是返回一个存根值。基本上,我想模拟MyQueryClass
.
So in my test case, I have used:
所以在我的测试用例中,我使用了:
MyQueryClass query = PowerMockito.mock(MyQueryClass.class);
PowerMockito.whenNew(MyQueryClass.class).withNoArguments().thenReturn(query);
when(query.getNextId()).thenReturn(1000000L);
boolean b = A.getInstance().myMethod(args);
//asserts
I used @RunWith(PowerMockRunner.class)
and @PrepareForTest({MyQueryClass.class})
in the beginning of my test class.
我在测试课开始时使用了@RunWith(PowerMockRunner.class)
和@PrepareForTest({MyQueryClass.class})
。
But when I debug the test, it is still calling the real method getNextId()
of the MyQueryClass
class.
但是我调试测试的时候,还是调用getNextId()
了MyQueryClass
类的真正方法。
What am I missing here? Can anyone help as I am new to Mockito and PowerMockito.
我在这里缺少什么?任何人都可以提供帮助,因为我是 Mockito 和 PowerMockito 的新手。
采纳答案by TrueDub
You need to put the class where the constructor is calledinto the @PrepareForTest
annotation instead of the class which is being constructed - see Mock construction of new objects.
您需要将调用构造函数@PrepareForTest
的类而不是正在构造的类放入注释中 - 请参阅新对象的模拟构造。
In your case:
在你的情况下:
? @PrepareForTest(MyQueryClass.class)
? @PrepareForTest(MyQueryClass.class)
? @PrepareForTest(A.class)
? @PrepareForTest(A.class)
More general:
更一般:
? @PrepareForTest(NewInstanceClass.class)
? @PrepareForTest(NewInstanceClass.class)
? @PrepareForTest(ClassThatCreatesTheNewInstance.class)
? @PrepareForTest(ClassThatCreatesTheNewInstance.class)
回答by ACV
As @TrueDub mentioned in his accepted reply, you need to add the class where the constructor is called to the @PrepareForTest
.
正如@TrueDub 在他接受的答复中提到的,您需要将调用构造函数的类添加到@PrepareForTest
.
However, if you do this, coverage for that class as reported by eclemma and Sonar will be zero for that class
但是,如果您这样做,则 eclemma 和 Sonar 报告的该类的覆盖率对于该类将为零
We are going to replace Javassist with ByteBuddy (#727) and it should help to resolve this old issue. But right now there is NO WAY TO USE PowerMock with JaCoCo On-the-fly instrumentation. And no workaround to get code coverage in IDE.
我们将用 ByteBuddy (#727) 替换 Javassist,它应该有助于解决这个老问题。但是现在没有办法将 PowerMock 与 JaCoCo On-the-fly 仪器一起使用。并且没有解决方法可以在 IDE 中获得代码覆盖率。
So the solution here would be to refactor the actual code to use a static factory that would return an instance of that class and then statically mock it.
因此,这里的解决方案是重构实际代码以使用静态工厂,该工厂将返回该类的实例,然后静态模拟它。
回答by jiajianchen
Perhaps you can simply use
也许你可以简单地使用
Mockito.doReturn(value).when(xxx)