我有一个DummyResource类和一个DummyTarget文件,以及一个测试类TestDummyResource,如下所示,但是模拟对象DummyResource dr = mock(DummyResource.class)
仅在我在普通类中调用构造函数时才有效,当它在匿名类中调用时,它调用实际的构造函数而不是使用模拟对象。
版本:
Powermock 1.4.12 mockito 1.9.0 Junit 4.8.2
虚拟目标.java:
import java.io.IOException;
import java.io.OutputStream;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;
public class DummyTarget {
public StreamingOutput testMocking() {
return new StreamingOutput() {
@Override
public void write(OutputStream arg0) throws IOException, WebApplicationException {
new DummyResource();
}
};
}
}
虚拟资源.java:
package com.smin.dummy;
public class DummyResource {
public DummyResource() {
System.out.println("mock failure");
}
}
TestDummyResource.java:
package com.smin.dummy;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.StreamingOutput;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({DummyResource.class,DummyTarget.class})
public class TestDummyResource {
@Before
public void setUp() throws Exception {
DummyResource dr = mock(DummyResource.class);
PowerMockito.whenNew(DummyResource.class).withNoArguments().thenReturn(dr);
}
@Test
public void testMocked() throws WebApplicationException, IOException {
new DummyResource(); // it uses the mocked object dr here,
//doesn't print "mock failure"
StreamingOutput sop = new DummyTarget().testMocking();
sop.write(null); // it calls DummyResource's constructor,
// prints ""mock failure"" here
}
}
您需要准备调用构造函数的类,而不是调用构造函数的类,以下内容应该可以修复您:
@PrepareForTest(DummyTarget.class)
有关更多信息,请查看此页面。
看起来匿名类可以继承定义它的类的包。 你能试试通配符形式的PrepareForTest
吗?
@PrepareForTest("com.smin.dummy.*")
如果这不起作用,您可以尝试使用霰弹枪PrepareEverythingForTest
注释。
实际上,您必须准备测试进行构造函数调用的类,而不是调用构造函数的类。请参阅 https://github.com/jayway/powermock/wiki/MockConstructor。
在您的情况下,您应该使用@PrepareForTest(DummyTarget.class)
我遇到了同样的问题,并使用具有完全限定名称的whenNew解决了它。在您的情况下,内部匿名类的完全限定名称为:
DummyTarget.class + "$1"
所以你应该创建一个该类的模拟:
DummyResource dr = mock(Class.forName(DummyTarget.class + "$1"));
它会为你工作。
另外,不要忘记准备DummyTarget类:
@PrepareForTest(DummyTarget.class)
希望有帮助=]