![](/img/trans.png)
[英]Mockito NullPointer Exception for the method called on Mock Object
[英]Mockito: Can't mock method called on object
我不允许发布真实代码,但这基本上是正在发生的事情:
我们有一个实现接口InterfaceOne
的 class InterfaceOneImpl
和一个实现InterfaceTwoImpl
的InterfaceTwo
InterfaceTwoImpl
在InterfaceOneImpl
中被实例化,并且InterfaceTwoImpl.makeHttpRequest()
被调用,但我需要在我的单元测试中模拟这个 function 因为我显然不想在其中发出 http 请求。 makeHttpRequest
是一个公共的、非静态的 function,它返回一个字符串
我的代码做这样的事情:
public class InterfaceOneImpl implements InterfaceOne{
public String processRequest(...){
...
InterfaceTwo obj = new InterfaceTwoImpl();
obj.makeHttpRequest();
...
}
}
我的测试 class 看起来像这样:
public TestInterfaceOneImpl {
....
@Test
public void testProcessRequest(){
InterfaceOne interfaceOneImpl = new InterfaceOneImpl();
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
PowerMockito.whenNew(RiskValidationRestClientImpl.class).withNoArguments().thenReturn((RiskValidationRestClientImpl) mock);
String reqStr = interfaceOneImpl.processRequest();
//a bunch of failed assertions
}
}
我的问题是 processRequest() 没有被正确模拟,因为该方法的源代码版本实际上正在运行而不是模拟。 当我在调试模式下单步执行单元测试的每一行时,我总是在 makeHttpRequest() function 的主体中结束。我做错了什么?
我的问题是 processRequest() 没有被正确模拟,因为该方法的源代码版本实际上正在运行而不是模拟。 当我在调试模式下单步执行单元测试的每一行时,我总是在 makeHttpRequest() function 的主体中结束。
我认为您的问题是错误的-根据您的示例, processRequest
是InterfaceOne
上的一种方法,而mock
是InterfaceTwo
的一个实例。
我假设你的意思是:
InterfaceTwo.when(mock.makeHttpRequest()).thenReturn("zzzz");
任何状况之下...
What am I doing wrong?
你认为你是 mocking 什么东西,但你根本不是。 让我们分解你的例子:
// First you create an instance of InterfaceOneImpl - OK
InterfaceOne interfaceOneImpl = new InterfaceOneImpl();
// Next you create a mock of InterfaceTwo (I think? I don't use PowerMock) - OK
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
// Then you tell the mock you created that it should return "zzzz" - OK
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
// Finally you call a method on your instance. YOU DO NOT USE "mock" in
// any way shape or form. As it's defined, "processRequest" creates a NEW
// instance of InterfaceTwo: InterfaceTwo obj = new InterfaceTwoImpl();
// and uses THAT instance. So of course you will always end up with the
// real method being called. You're creating a mock and literally never
// using it.
String reqStr = interfaceOneImpl.processRequest();
修复:实际使用你的模拟。 通过在 function 中传递它:
// Pass the object to use as an argument
public String processRequest(InterfaceTwo obj){
...
obj.makeHttpRequest();
...
}
// And then your test:
@Test
public void testProcessRequest() {
InterfaceOne interfaceOneImpl = new InterfaceOneImpl();
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
// NOW you can use the mock
String reqStr = interfaceOneImpl.processRequest(mock);
}
或者将其传递给 class:
public class InterfaceOneImpl implements InterfaceOne {
public InterfaceOneImpl(InterfaceTwo obj) {
this.obj = obj;
}
public String processRequest(...){
...
obj.makeHttpRequest();
...
}
}
// And then your test
@Test
public void testProcessRequest(){
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
// Now interface one will use the mock to do the request
InterfaceOne interfaceOneImpl = new InterfaceOneImpl(mock);
String reqStr = interfaceOneImpl.processRequest();
//a bunch of failed assertions
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.