英文:
How could I mock this and make sure to not get back null?
问题
以下是翻译好的内容:
我有以下要进行单元测试的类:
@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")
// 很多查询参数,不重要
.build()
)
.accept(MediaType.APPLICATION_JSON)
.acceptCharset(StandardCharsets.UTF_8)
.retrieve();
}
}
这是我的测试类:
@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);
service.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);
service.search();
}
}
在`.accept(MediaType.APPLICATION_JSON)`这一行发生异常(`NullPointerException`),因为`uri()`返回null,代码试图在null对象上调用`.accept()`方法。
我不能更改`Service`类。我只能更改我的测试类。不确定如何使其工作。
编辑:我已经使它工作,参考了答案。
英文:
I have the following class that I want to unit test:
@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();
}
}
This is my test 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("");
}
}
An exception (NullPointerException
) happens in the line of .accept(MediaType.APPLICATION_JSON)
because the uri()
returns null and the code tries to call method .accept()
on a null object.
I am not let to change the Service
class. I can change only my test class. Not sure how could I make it to work.
Edit: I made it to work, read answers.
答案1
得分: 2
所以实际上我将这个地方进行了修改:
lenient().when(uriSpecMock.uri(Mockito.any(URI.class))).thenReturn(headersSpecMock);
改为了这样:
lenient().when(uriSpecMock.uri(Mockito.any(Function.class))).thenReturn(headersSpecMock);
而且它有效地运行了。
英文:
So actually I changed this:
lenient().when(uriSpecMock.uri(Mockito.any(URI.class))).thenReturn(headersSpecMock);
to this:
lenient().when(uriSpecMock.uri(Mockito.any(Function.class))).thenReturn(headersSpecMock);
And it works good.
答案2
得分: 1
I think this is the problem
when(uriSpecMock.uri(Mockito.any(URI.class)))
you mocked uri to return something when it receives something that's URI
class but you're using a lambda function.
The method signature is
S uri(Function<UriBuilder, URI> uriFunction);
Try changing it to
when(uriSpecMock.uri(Mockito.any(Function.class)))
Also check this for future use, quite a good article
https://www.baeldung.com/spring-mocking-webclient
英文:
I think this is the problem
when(uriSpecMock.uri(Mockito.any(URI.class)))
you mocked uri to return something when it receives something that's URI
class but you're using a lambda function.
The method signature is
S uri(Function<UriBuilder, URI> uriFunction);
Try changing it to
when(uriSpecMock.uri(Mockito.any(Function.class)))
Also check this for future use, quite a good article
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论