Using PowerMockito.whenNew() is not getting mocked and original method is called

我有一个类似下面这样的代码:

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;
}
}

现在我正在为 A.myMethod(someargs)写一个测试。我想跳过实际的方法 query.getNextId(),而是返回一个存根值。基本上,我想模仿 MyQueryClass

所以在我的测试用例中,我使用了:

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

我在测试类的开头使用了 @RunWith(PowerMockRunner.class)@PrepareForTest({MyQueryClass.class})

但是当我调试测试时,它仍然在调用 MyQueryClass类的实际方法 getNextId()

What am I missing here? Can anyone help as I am new to Mockito and PowerMockito.

102573 次浏览

您需要将 构造函数称为所在的类放入 @PrepareForTest注释中,而不是正在构造的类-参见 新对象的模拟构造

就你而言:

Something @PrepareForTest(MyQueryClass.class)

@PrepareForTest(A.class)

更一般的说法:

Something @PrepareForTest(NewInstanceClass.class)

@PrepareForTest(ClassThatCreatesTheNewInstance.class)

正如@TrueDub 在他接受的回复中提到的,您需要将构造函数调用的类添加到 @PrepareForTest

However, if you do this, coverage for that class as reported by eclemma and Sonar will be zero for that class

维基百科

我们将用 ByteBuddy (# 727)取代 Javhelp,它应该可以 help to resolve this old issue. But right now there is NO WAY TO USE 带有 JaCoCo 即时工具的 PowerMock 在 IDE 中获得代码覆盖率。

因此,这里的解决方案是重构实际的代码,使用一个静态工厂,该工厂将返回该类的一个实例,然后静态模拟它。

也许你只需要

Mockito.doReturn(value).when(xxx)