使用Mockito Mock WebClient调用中的Mono.just时出现NullPointerException求助
问题根因
- 链式调用返回类型不匹配:
WebClient.method(HttpMethod.DELETE)实际返回类型是RequestBodyUriSpec,你当前直接返回RequestBodySpec类型的Mock对象,类型不匹配导致链式调用第一步就返回null,后续方法调用全部触发空指针。 - Mock匹配规则不生效:你在
body方法的桩逻辑中使用Mono.just(request)作为入参匹配条件,业务代码中实际传入的是Mono.just(req),两个是不同的Mono实例,Mockito默认使用equals匹配,无法命中桩规则,导致body方法返回null,后续调用retrieve()时触发空指针。 - 变量名拼写错误:你代码中Mock的变量是
requestHeaderSpec,但部分行写成了requestHeadersSpec(多了个s),变量未初始化导致返回null。 - 语法错误:
when(webClient.method(HttpMethod.DELETE).thenReturn(requestBodySpec)缺少右括号,运行时会直接出错。
解决方案
前置检查
首先确认测试类已经开启Mockito注解支持:
- JUnit4:类上添加
@RunWith(MockitoJUnitRunner.class) - JUnit5:类上添加
@ExtendWith(MockitoExtension.class)
修正后完整Mock代码
@Mock WebClient webClient; @Mock WebClient.RequestBodyUriSpec requestBodyUriSpec; @Mock WebClient.RequestHeadersSpec requestHeadersSpec; @Mock WebClient.ResponseSpec responseSpec; // 预先构造测试用的请求、返回实例 Request testRequest = new Request(); Response testResponse = new Response(); @Test void testDeleteApiCall() { // 匹配method调用,返回对应类型的Mock对象 when(webClient.method(HttpMethod.DELETE)).thenReturn(requestBodyUriSpec); // 匹配header、contentType调用,返回自身维持链式调用 when(requestBodyUriSpec.header(anyString(), anyString())).thenReturn(requestBodyUriSpec); when(requestBodyUriSpec.contentType(any(MediaType.class))).thenReturn(requestBodyUriSpec); // 用泛型匹配器匹配body参数,避免实例匹配失败 when(requestBodyUriSpec.body(any(Mono.class), eq(Request.class))).thenReturn(requestHeadersSpec); // 匹配后续retrieve和响应转换逻辑 when(requestHeadersSpec.retrieve()).thenReturn(responseSpec); when(responseSpec.bodyToMono(eq(Response.class))).thenReturn(Mono.just(testResponse)); // 此处调用你的业务逻辑 // xxx.execute(testRequest); // 可选:添加业务逻辑断言 }
补充说明
不需要单独MockMono.just对象,Mono是Reactor的纯内存操作类,直接构造实际实例传入即可,问题本质和Mono本身无关。
如果需要校验传入body的Request参数是否符合预期,可以使用参数捕获器实现:
// 声明参数捕获器 ArgumentCaptor<Mono<Request>> monoCaptor = ArgumentCaptor.forClass(Mono.class); when(requestBodyUriSpec.body(monoCaptor.capture(), eq(Request.class))).thenReturn(requestHeadersSpec); // 执行业务逻辑后捕获参数验证 Request actualRequest = monoCaptor.getValue().block(); assertEquals(testRequest, actualRequest);
内容的提问来源于stack exchange,提问作者Sumathi Kotthuri
相关产品推荐
相关产品推荐

