我怎么能嘲笑这个并确保不返回 null?
How could I mock this and make sure to not get back null?
我有以下 class 想要进行单元测试:
@RequiredArgsConstructor
@Service
public class Service {
private final WebClient.Builder builder;
private WebClient webClient;
@PostConstruct
public void init() {
searchUri = "/search-uri";
webClient = builder.baseUrl(searchUri)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
}
public ResponseSpec search() {
return webClient
.get()
.uri(uriBuilder ->
uriBuilder
.path("/search-uri")
// alot of query param, not important
.build()
)
.accept(MediaType.APPLICATION_JSON)
.acceptCharset(StandardCharsets.UTF_8)
.retrieve();
}
}
这是我的测试class:
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class ServiceTest {
@InjectMocks
private Service service;
@Mock
private WebClient webClient;
@Mock
private Builder builder;
@Test
public void testSearch() {
when(builder.baseUrl(Mockito.anyString())).thenReturn(builder);
when(builder.defaultHeader(Mockito.anyString(), Mockito.anyString())).thenReturn(builder);
when(builder.build()).thenReturn(webClient);
issuerServiceImpl.init();
WebClient.RequestHeadersUriSpec uriSpecMock = mock(WebClient.RequestHeadersUriSpec.class);
WebClient.RequestHeadersSpec headersSpecMock = mock(WebClient.RequestHeadersSpec.class);
WebClient.ResponseSpec responseSpecMock = mock(WebClient.ResponseSpec.class);
when(webClient.get()).thenReturn(uriSpecMock);
lenient().when(uriSpecMock.uri(Mockito.any(URI.class))).thenReturn(headersSpecMock);
issuerServiceImpl.searchIssuers("");
}
}
异常 (NullPointerException
) 发生在 .accept(MediaType.APPLICATION_JSON)
行中,因为 uri()
returns null 并且代码尝试调用方法 .accept()
空对象。
我不让改Service
class。我只能更改我的测试 class。不确定我怎样才能让它工作。
编辑:我做到了,阅读答案。
我认为这是问题所在
when(uriSpecMock.uri(Mockito.any(URI.class)))
当它收到 URI
class 的东西时,你将 uri 嘲笑为 return 东西,但你使用的是 lambda 函数。
方法签名是
S uri(Function<UriBuilder, URI> uriFunction);
尝试将其更改为
when(uriSpecMock.uri(Mockito.any(Function.class)))
也看看这个以备后用,不错的文章
所以实际上我改变了这个:
lenient().when(uriSpecMock.uri(Mockito.any(URI.class))).thenReturn(headersSpecMock);
对此:
lenient().when(uriSpecMock.uri(Mockito.any(Function.class))).thenReturn(headersSpecMock);
而且效果很好。
我有以下 class 想要进行单元测试:
@RequiredArgsConstructor
@Service
public class Service {
private final WebClient.Builder builder;
private WebClient webClient;
@PostConstruct
public void init() {
searchUri = "/search-uri";
webClient = builder.baseUrl(searchUri)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
}
public ResponseSpec search() {
return webClient
.get()
.uri(uriBuilder ->
uriBuilder
.path("/search-uri")
// alot of query param, not important
.build()
)
.accept(MediaType.APPLICATION_JSON)
.acceptCharset(StandardCharsets.UTF_8)
.retrieve();
}
}
这是我的测试class:
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class ServiceTest {
@InjectMocks
private Service service;
@Mock
private WebClient webClient;
@Mock
private Builder builder;
@Test
public void testSearch() {
when(builder.baseUrl(Mockito.anyString())).thenReturn(builder);
when(builder.defaultHeader(Mockito.anyString(), Mockito.anyString())).thenReturn(builder);
when(builder.build()).thenReturn(webClient);
issuerServiceImpl.init();
WebClient.RequestHeadersUriSpec uriSpecMock = mock(WebClient.RequestHeadersUriSpec.class);
WebClient.RequestHeadersSpec headersSpecMock = mock(WebClient.RequestHeadersSpec.class);
WebClient.ResponseSpec responseSpecMock = mock(WebClient.ResponseSpec.class);
when(webClient.get()).thenReturn(uriSpecMock);
lenient().when(uriSpecMock.uri(Mockito.any(URI.class))).thenReturn(headersSpecMock);
issuerServiceImpl.searchIssuers("");
}
}
异常 (NullPointerException
) 发生在 .accept(MediaType.APPLICATION_JSON)
行中,因为 uri()
returns null 并且代码尝试调用方法 .accept()
空对象。
我不让改Service
class。我只能更改我的测试 class。不确定我怎样才能让它工作。
编辑:我做到了,阅读答案。
我认为这是问题所在
when(uriSpecMock.uri(Mockito.any(URI.class)))
当它收到 URI
class 的东西时,你将 uri 嘲笑为 return 东西,但你使用的是 lambda 函数。
方法签名是
S uri(Function<UriBuilder, URI> uriFunction);
尝试将其更改为
when(uriSpecMock.uri(Mockito.any(Function.class)))
也看看这个以备后用,不错的文章
所以实际上我改变了这个:
lenient().when(uriSpecMock.uri(Mockito.any(URI.class))).thenReturn(headersSpecMock);
对此:
lenient().when(uriSpecMock.uri(Mockito.any(Function.class))).thenReturn(headersSpecMock);
而且效果很好。