用 Mockito 模拟接口 return 一个 NullPointerException
Mock an Interface with Mockito return a NullPointerException
我正在尝试为一个 project.I 遇到问题创建单元测试,因为当我尝试控制接口(模拟)的结果时。当代码获取 return 一个 NullPointerException.
的接口变量时
首先我在我的测试class (ClassA) 中尝试了@Override 方法,但它不起作用。之后我尝试模拟接口对象并使用 Mockito.When().tehnReturn();
控制行为
我会把我的代码放在这里,我阅读了一些解决方案,但 none 有效。
我的界面:
@FunctionalInterface
public interface Interface {
UpdateXResponse process(UpdateXRequest request) throws Exception;
}
我要测试的class:
@Service(ClassA.class)
public class ClassA extends VService implements UpdateX {
@Reference
@Inject
private Interface interface;
@Inject
public ClassA(...) {...}
@Override
public UpdateXResponse process(UpdateXRequest request) throws Exception {
UpdateXResponse response = initResponse(context, request, new UpdateXResponse());
UpdateXInput input = request.getInput();
UpdateXOutput output = new UpdateXOutput();
response.setOutput(output);
try {
firstMethodCall(...);
} catch (Exception t) {
throwCorrectException(t, logger);
}
return response;
}
private void firstMethodCall(...) throws Exception {
TypeF typeF = callInterfaceMethod(...);
...
}
/**
* Orchestrates Interface service
*/
protected TypeF callInterfaceMethod(...) {
...
request.setInput(input);
request.setHeader(header);
InterfaceResponse response = interface.process(request); // LINE ERROR - In this step interface is NULL when the test get this
return response;
}
}
最后是我的 class 测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest(value = {ClassA.class,Interface.class} )
public class WithPowerMockUnitTest{
@InjectMocks
private ClassA classA;
private Interface interface;
@Before
public void setUp() throws Exception {
InterfaceRequest InterfaceRequest = createInterfaceRequest();
InterfaceResponse serviceUnavailableResponse = createInterfaceResponse();
Interface = Mockito.mock(Interface.class);
when(Interface.process(Mockito.any(InterfaceRequest.class))).thenReturn(serviceUnavailableResponse);
}
@Test
public void testh() throws SOAException {
InterfaceResponse res = interface.process(Mockito.any(InterfaceRequest.class)); // There all run ok. The interface is not null and return what i expected.
System.out.println("RES "+res);
}
@Test
public void test() {
assertNotNull(classA); // not null
assertNotNull(interface); // not null
}
@Test
public void newTest() throws Exception {
InterfaceRequest InterfaceRequest = createInterfaceRequest();
InterfaceResponse serviceUnavailableResponse = createInterfaceResponse();
UpdateXResponse response = ClassA.process(updateXRequest()); // PROBLEM!! When that get the LINE ERROR the interface is null! WHY?
}
}
我在存在问题的行中添加了一些注释。
public interface A{
Response process(Request r) throws Exception;
}
public class B{
private Class_That_Override_Interface_method ctoim;
public Response function(){
X res = method_B();
}
protected X method_B(){
response res = ctoim.process(request); // That ctoim is always NULL when the test get that line/call
}
}
谢谢
您缺少 Interface
变量上的 @Mock
注释。
因此,模拟不会注入您的 classA
并且 newTest()
失败。 (在这种情况下,从 setUp
方法中删除 Interface = Mockito.mock(Interface.class);
)。
或者删除 @InjectMocks
注释并创建你的 class 测试手动传递你的模拟到构造函数。
对于这个具体案例(假设它与上一个问题不同)
PowerMockito
似乎没有必要参与。因此,除非您遗漏了一些相关部分,否则您不妨使用 MockitoJUnitRunner
.
Ps.:
还记得我上次说的 compilable
个例子吗?
interface
是关键字,不能用于变量。
- 您还应该始终编写相同的变量(不是
Interface
和 interface
/ classA
和 ClassA
)
如果您还没有阅读它,请查看有关 minmal reproducible examples 的帮助部分。
编辑:
我忘了提 testh()
中的行 interface.process(Mockito.any(InterfaceRequest.class));
实际上是无效语法。您应该仅将 ArgumentMatchers
用于模拟方法的参数。
在使用 PowerMockRunner
.
时,还可以考虑将 MockitoAnnotations.initMocks(this);
添加到 setUp
方法中
我正在尝试为一个 project.I 遇到问题创建单元测试,因为当我尝试控制接口(模拟)的结果时。当代码获取 return 一个 NullPointerException.
的接口变量时首先我在我的测试class (ClassA) 中尝试了@Override 方法,但它不起作用。之后我尝试模拟接口对象并使用 Mockito.When().tehnReturn();
控制行为我会把我的代码放在这里,我阅读了一些解决方案,但 none 有效。
我的界面:
@FunctionalInterface
public interface Interface {
UpdateXResponse process(UpdateXRequest request) throws Exception;
}
我要测试的class:
@Service(ClassA.class)
public class ClassA extends VService implements UpdateX {
@Reference
@Inject
private Interface interface;
@Inject
public ClassA(...) {...}
@Override
public UpdateXResponse process(UpdateXRequest request) throws Exception {
UpdateXResponse response = initResponse(context, request, new UpdateXResponse());
UpdateXInput input = request.getInput();
UpdateXOutput output = new UpdateXOutput();
response.setOutput(output);
try {
firstMethodCall(...);
} catch (Exception t) {
throwCorrectException(t, logger);
}
return response;
}
private void firstMethodCall(...) throws Exception {
TypeF typeF = callInterfaceMethod(...);
...
}
/**
* Orchestrates Interface service
*/
protected TypeF callInterfaceMethod(...) {
...
request.setInput(input);
request.setHeader(header);
InterfaceResponse response = interface.process(request); // LINE ERROR - In this step interface is NULL when the test get this
return response;
}
}
最后是我的 class 测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest(value = {ClassA.class,Interface.class} )
public class WithPowerMockUnitTest{
@InjectMocks
private ClassA classA;
private Interface interface;
@Before
public void setUp() throws Exception {
InterfaceRequest InterfaceRequest = createInterfaceRequest();
InterfaceResponse serviceUnavailableResponse = createInterfaceResponse();
Interface = Mockito.mock(Interface.class);
when(Interface.process(Mockito.any(InterfaceRequest.class))).thenReturn(serviceUnavailableResponse);
}
@Test
public void testh() throws SOAException {
InterfaceResponse res = interface.process(Mockito.any(InterfaceRequest.class)); // There all run ok. The interface is not null and return what i expected.
System.out.println("RES "+res);
}
@Test
public void test() {
assertNotNull(classA); // not null
assertNotNull(interface); // not null
}
@Test
public void newTest() throws Exception {
InterfaceRequest InterfaceRequest = createInterfaceRequest();
InterfaceResponse serviceUnavailableResponse = createInterfaceResponse();
UpdateXResponse response = ClassA.process(updateXRequest()); // PROBLEM!! When that get the LINE ERROR the interface is null! WHY?
}
}
我在存在问题的行中添加了一些注释。
public interface A{
Response process(Request r) throws Exception;
}
public class B{
private Class_That_Override_Interface_method ctoim;
public Response function(){
X res = method_B();
}
protected X method_B(){
response res = ctoim.process(request); // That ctoim is always NULL when the test get that line/call
}
}
谢谢
您缺少 Interface
变量上的 @Mock
注释。
因此,模拟不会注入您的 classA
并且 newTest()
失败。 (在这种情况下,从 setUp
方法中删除 Interface = Mockito.mock(Interface.class);
)。
或者删除 @InjectMocks
注释并创建你的 class 测试手动传递你的模拟到构造函数。
对于这个具体案例(假设它与上一个问题不同)
PowerMockito
似乎没有必要参与。因此,除非您遗漏了一些相关部分,否则您不妨使用 MockitoJUnitRunner
.
Ps.:
还记得我上次说的 compilable
个例子吗?
interface
是关键字,不能用于变量。- 您还应该始终编写相同的变量(不是
Interface
和interface
/classA
和ClassA
)
如果您还没有阅读它,请查看有关 minmal reproducible examples 的帮助部分。
编辑:
我忘了提 testh()
中的行 interface.process(Mockito.any(InterfaceRequest.class));
实际上是无效语法。您应该仅将 ArgumentMatchers
用于模拟方法的参数。
在使用 PowerMockRunner
.
MockitoAnnotations.initMocks(this);
添加到 setUp
方法中