我试图为一个项目创建单元测试。我面临一个问题,因为当我尝试控制接口(模拟)的结果时。当代码获取返回NullPointerException的Interface变量时。
首先,我尝试在测试类(ClassA)中使用@Override方法,但该方法无效。之后,我尝试模拟接口对象并使用Mockito.When()。tehnReturn();
来控制命令区。我将把我的代码放在这里,我读了一些解决方案,但没有用。
我的界面:
@FunctionalInterface
public interface Interface {
UpdateXResponse process(UpdateXRequest request) throws Exception;
}
我要测试的课程:
@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;
}
}
最后是我的课堂测试:
@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
}
}
谢谢
您缺少@Mock
变量上的Interface
注释。因此,该模拟不会注入到您的classA
中,并且newTest()
将失败。 (在这种情况下,请从Interface = Mockito.mock(Interface.class);
方法中删除setUp
。)>
可替代地删除@InjectMocks
批注,并手动将您的模拟传递到构造函数中,以创建要测试的类。
对于此特定情况(假设其与上一个问题不同)似乎没有必要涉及PowerMockito
。因此,除非您遗漏了一些相关的部分,否则您最好只使用MockitoJUnitRunner
。
Ps .:还记得我上次对compilable
示例所说的话吗?
interface
是关键字,不能用于变量。Interface
和interface
/ classA
和ClassA
)并且如果您还没有阅读它,请查看有关minmal reproducible examples的帮助部分。
编辑:
我不得不提到interface.process(Mockito.any(InterfaceRequest.class));
中的testh()
行实际上是无效的语法。您只应将ArgumentMatchers
用于模拟方法的参数。
使用MockitoAnnotations.initMocks(this);
时,也请考虑将MockitoAnnotations.initMocks(this);
添加到setUp
方法中。