我正在尝试测试一个方法sendEmail
。我想对这个方法做一个阴性测试。我想接IllegalStateException
的案子。sendemail
方法在我的ServiceClient类中。在测试中,我模拟了serviceClient
和apiClient
,该方法的代码如下所示:
public HttpStatus sendEmail(){
Supplier<HttpStatus> apiRequest = apiclient.post(command);
return retry(apiRequest).orElseThrow(() -> new IllegalStateException());
}
private <T> Optional<T> retry(Supplier<T> apiRequest) {
T result = apiRequest.get();
if (result != null) {
return Optional.of(result);
}
result = apiRequest.get();
if (result != null) {
return Optional.of(result);
}
return Optional.empty();
}
我试图运行的测试看起来像这个
@Test
void sendEmailShouldThrowIllegalStateException() {
when(apiclient.post(any())
.thenReturn(null, null);
assertThrows(IllegalStateException.class,
() -> serviceClient
.sendEndpointRegistrationEmail());
}
我认为这会起作用,因为mock方法应该返回null
,这将触发异常,但它抛出
org.opentest4j.AssertionFailedError: Unexpected exception type thrown ==> expected: <java.lang.IllegalStateException> but was: <java.lang.NullPointerException>
只是为了澄清这个问题并不是说我得到了NPE。问题是抛出了错误的异常。
实际上,报告的异常NullPointerException
是很自然的。
下面是通过你的代码发生的事情:
- 您指示
apiclient
mock在调用#post
方法时返回null
- 在测试夹具中,您使用
serviceClient
调用了serviceClient#sendEndpointRegistrationEmail
(我想已经注入了apiclient
mock( - 当调用上述方法时,它将导致对
retry(Supplier<T> apiRequest)
的调用,其中apiRequest
参数为null(模拟调用的结果( - CCD_ 16将导致CCD_ 17,因为CCD_
然后,解决方案是为任何apiclient.post(any())
调用返回一个mock,并将后者配置为在调用Supplier<HttpStatus>#get
时返回null
:
@Test
public void sendEmailShouldThrowIllegalStateException() {
// create a Supplier mock for your request result
Supplier apiRequestMock = Mockito.mock(Supplier.class);
when(apiRequestMock.get()).thenReturn(null);
// use the Supplier mock as return result
when(apiclient.post(any())).thenReturn(apiRequestMock);
assertThrows(IllegalStateException.class,
() -> serviceClient
.sendEndpointRegistrationEmail());
}