我怎么能嘲笑这个并确保不返回 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()空对象。

我不让改Serviceclass。我只能更改我的测试 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)))

也看看这个以备后用,不错的文章

https://www.baeldung.com/spring-mocking-webclient

所以实际上我改变了这个:

lenient().when(uriSpecMock.uri(Mockito.any(URI.class))).thenReturn(headersSpecMock);

对此:

lenient().when(uriSpecMock.uri(Mockito.any(Function.class))).thenReturn(headersSpecMock);

而且效果很好。