Mockito模拟HttpResponse<String>遇WrongTypeOfReturnValue错误求助
解决Mockito测试HttpClient时的WrongTypeOfReturnValue错误
问题背景
使用java.net.http.HttpClient编写单元测试时,业务代码运行正常,但执行测试时抛出org.mockito.exceptions.misusing.WrongTypeOfReturnValue错误,错误提示:
HttpResponse$MockitoMock$35694822 cannot be returned by toString()
toString() should return String
测试代码中通过@Spy注解创建了HttpClient的Spy对象,并尝试用when(httpClient.send(...)).thenReturn(mockResponse)存根send方法,错误就出在这行代码。
错误原因
- Spy对象存根方式错误:使用
when(spy.method()).thenReturn()语法时,Mockito会先执行一次原方法,而HttpClient.send()在测试环境下执行会触发内部逻辑,导致返回值类型处理混乱,进而引发toString()的类型匹配错误。 - 参数匹配逻辑不合理:
any(HttpResponse.BodyHandlers.ofString().getClass())的写法存在问题,BodyHandlers.ofString()返回的是内部类实例,用这种方式匹配参数容易导致匹配失效,间接引发存根逻辑异常。
解决方案
1. 改用Spy对象的安全存根语法
针对Spy对象,必须使用doReturn(...).when(spy).method()的语法存根,这种方式不会触发原方法执行,避免测试环境下原方法运行带来的错误。
2. 修正参数匹配逻辑
使用泛型类型匹配参数,比如any(HttpRequest.class)和any(BodyHandler.class),确保参数匹配准确。如果需要精确匹配指定的BodyHandler,可以使用eq(HttpResponse.BodyHandlers.ofString())。
修改后的测试代码
@Mock HttpResponse<String> mockResponse; @Spy HttpClient httpClient; @Test void callExternalApi_success(){ when(mockResponse.body()).thenReturn("Testing body"); // 修正存根方式和参数匹配 doReturn(mockResponse).when(httpClient).send(any(HttpRequest.class), any(BodyHandler.class)); String url = "http://testing-url"; String externalApi = openPagesExternalApi.callExternalApi(url); assertEquals(externalApi, "Testing body"); }
如果需要精确匹配BodyHandlers.ofString(),可以替换为:
doReturn(mockResponse).when(httpClient).send(any(HttpRequest.class), eq(HttpResponse.BodyHandlers.ofString()));
额外说明
- 确保测试类上添加了
@ExtendWith(MockitoExtension.class)(JUnit 5)或@RunWith(MockitoJUnitRunner.class)(JUnit 4),保证@Spy和@Mock注解能正常初始化对象。 - 业务代码中的
conn变量需要注入测试中的httpClientSpy对象,否则测试存根逻辑不会生效。
内容的提问来源于stack exchange,提问作者Harmeet Kaur
相关产品推荐
相关产品推荐

