怎么样才能模拟这个并确保不会得到空值?

huangapple go评论74阅读模式
英文:

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&lt;UriBuilder, URI&gt; 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

huangapple
  • 本文由 发表于 2020年9月16日 16:38:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63916258.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定