我有一个名为MyXStream的内部私有类,它扩展了com.thoughtworks.xstream.XStream
。
OuterClass.java
public class OuterClass {
private class MyXStream extends XStream {
@Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
// implementation details
}
}
public void myMethod() {
XStream myXStream = new MyXStream();
}
}
我使用的测试用例
OuterClassTest.java
Class myXStreamClass = Whitebox.getInnerClassType(OuterClass.class, "MyXStream");
XStream xStream = (XStream) PowerMockito.mock(myXStreamClass);
PowerMockito.whenNew(myXStreamClass).withNoArguments().thenReturn(xStream);
它不起作用。 myXStream
为null并导致NullPointerException。然后我尝试向MyXStream添加一个构造函数,看看发生了什么:
public class OuterClass {
private class MyXStream extends XStream {
public MyXStream() {
// some debug statements
}
@Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
// implementation details
}
}
}
测试案例有效。
我也可以将withNoArguments()
替换为withAnyArguments()
,这也有效。像这样:
OuterClassTest.java
Class myXStreamClass = Whitebox.getInnerClassType(OuterClass.class, "MyXStream");
XStream xStream = (XStream) PowerMockito.mock(myXStreamClass);
PowerMockito.whenNew(myXStreamClass).withAnyArguments().thenReturn(xStream);
我只是想知道为什么我不能只使用withNoArguments()
如果我没有指定任何构造函数? Java编译器不应该为我创建一个空的吗?它们之间有什么区别?
更新
最小,完整且可验证的示例
OuterClass.java
package test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.mapper.MapperWrapper;
public class OuterClass {
private class MyXStream extends XStream {
@Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
return null;
}
}
public void myMethod() {
XStream myXStream = new MyXStream();
myXStream.fromXML("xml");
}
}
OuterClassTest.java
package test;
import com.thoughtworks.xstream.XStream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
@RunWith(PowerMockRunner.class)
@PrepareForTest({
OuterClass.class
})
public class OuterClassTest {
private OuterClass outerClass;
@Before
public void setUp() {
outerClass = PowerMockito.spy(new OuterClass());
}
@Test
public void myMethod() throws Exception {
Class myXStreamClass = Whitebox.getInnerClassType(OuterClass.class, "MyXStream");
XStream xStream = (XStream) PowerMockito.mock(myXStreamClass);
// withAnyArguments() worked
// PowerMockito.whenNew(myXStreamClass).withAnyArguments().thenReturn(xStream);
// withNoArguments() will cause java.lang.NullPointerException
PowerMockito.whenNew(myXStreamClass).withNoArguments().thenReturn(xStream);
outerClass.myMethod();
Mockito.verify(xStream, Mockito.times(1)).fromXML("xml");
}
}
我意识到直接在代码中调用new
不适合测试,但我发现PowerMockito可以模拟新实例并且有一些奇怪的行为并且不知道原因。
为什么withNoArguments()即使我的new
语句不起作用也不会传递任何参数?
为什么在MyXStream中添加空构造函数可以解决这个问题?