You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何Mock接收实体类请求且需调用block()方法的WebClient?

问题描述

我想要Mock一个接收实体类作为请求参数、且需要调用.block()方法将Mono转换为目标类的WebClient。需要Mock的调用代码如下:

response = webClientSample.post().uri(builder.toUriString())
                .headers(httpHeader -> httpHeader.addAll(httpHeaders))
                .body(BodyInserters.fromValue(SampleRequest)).retrieve().bodyToMono(SampleResponse.class).block();

当前Mock代码运行时,上述调用链的.body(...).retrieve().bodyToMono(...).block()部分抛出空指针异常。我尝试通过以下代码Mock block()方法(populateSampleResponse为返回SampleResponse实例的方法):

Mockito.when(Mono.just(populateSampleResponse()).block()).thenReturn(populateSampleResponse());

但触发报错:

org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);

解决方案

你不能直接Mock Mono.block(),因为Mono.just(...)返回的是真实Mono实例,并非Mockito生成的Mock对象,所以会触发方法调用错误。正确做法是按WebClient的调用链,逐步Mock每个环节的返回对象:

  1. 初始化WebClient Mock实例
    确保webClientSample是Mock对象,可通过注解或手动初始化:

    WebClient webClientSample = Mockito.mock(WebClient.class);
    // 或使用@Mock注解配合MockitoAnnotations.openMocks(this)
    
  2. Mock post()方法的返回值

    WebClient.RequestBodyUriSpec requestBodyUriSpec = Mockito.mock(WebClient.RequestBodyUriSpec.class);
    Mockito.when(webClientSample.post()).thenReturn(requestBodyUriSpec);
    
  3. Mock uri()方法的返回值

    Mockito.when(requestBodyUriSpec.uri(Mockito.anyString())).thenReturn(requestBodyUriSpec);
    
  4. Mock headers()方法的返回值

    Mockito.when(requestBodyUriSpec.headers(Mockito.any(Consumer.class))).thenReturn(requestBodyUriSpec);
    
  5. Mock body()方法的返回值

    WebClient.RequestHeadersSpec requestHeadersSpec = Mockito.mock(WebClient.RequestHeadersSpec.class);
    // 匹配任意BodyInserter,也可根据需要精确匹配SampleRequest参数
    Mockito.when(requestBodyUriSpec.body(Mockito.any(BodyInserter.class))).thenReturn(requestHeadersSpec);
    
  6. Mock retrieve()方法的返回值

    WebClient.ResponseSpec responseSpec = Mockito.mock(WebClient.ResponseSpec.class);
    Mockito.when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
    
  7. Mock bodyToMono()及block()方法
    Mock一个Mono对象,让它的block()返回预期的SampleResponse实例:

    Mono<SampleResponse> mockMono = Mockito.mock(Mono.class);
    Mockito.when(responseSpec.bodyToMono(SampleResponse.class)).thenReturn(mockMono);
    Mockito.when(mockMono.block()).thenReturn(populateSampleResponse());
    

如果使用Spring Boot 2.3+,也可以考虑使用WebClientTest切片测试,它会自动配置WebClient的Mock环境,简化Mock代码。

内容的提问来源于stack exchange,提问作者cwf8951

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:30:46