如何Mock WebClient bodyToMono方法中的泛型Class<T>对象
解决方案
1. 先修正Service方法的两处错误
你的泛型方法存在明显的写法问题,不修正的话业务逻辑本身就有问题:
- 返回类型错误:
bodyToMono(...).block()返回的是泛型对象T,不是Class<T>,所以方法签名要改成T? bodyToMono参数冗余:传入的responseType本身就是Class<T>类型,不需要再加::class.java
修正后的Service方法:
fun <T : Any> post(uri: String, body: Any, responseType: Class<T>): T? { return webClient.post() .uri(uri) .bodyValue(body) .retrieve() .bodyToMono(responseType) .block() }
2. 用Mockito任意参数匹配器适配泛型场景
你当前只Mock了传入ResponseDTO::class.java的特定情况,但泛型方法调用时传入的是参数responseType,改用任意Class匹配器就能覆盖泛型调用的场景:
替换测试代码里的这行:
`when`(responseMock.bodyToMono(ResponseDTO::class.java)).thenReturn(Mono.just(responseDTO))
为:
`when`(responseMock.bodyToMono(any(Class::class.java))).thenReturn(Mono.just(responseDTO))
如果需要更严格的类型约束,也可以用泛型版匹配器:
`when`(responseMock.bodyToMono(any<Class<ResponseDTO>>())).thenReturn(Mono.just(responseDTO))
3. 修正Mock对象的类型错误
原测试里requestHeadersMock的类型写错了,bodyValue方法返回的是WebClient.RequestHeadersSpec<*>,不是RequestBodyUriSpec,修正后才能保证Mock链的正确性。
完整测试代码示例
@Mock lateinit var mockWebClient: WebClient @Mock private lateinit var requestHeadersMock: WebClient.RequestHeadersSpec<*> @Mock private lateinit var responseMock: WebClient.ResponseSpec @Mock private lateinit var requestBodyUriMock: WebClient.RequestBodyUriSpec @Mock private lateinit var requestBodyMock: WebClient.RequestBodySpec private lateinit var webclient: Service @BeforeEach fun setUp() { MockitoAnnotations.openMocks(this) webclient = Service(mockWebClient) } @Test fun testPost() { val uri = "/path" val requestDTO = RequestDTO(...) // 初始化你的请求DTO实例 val responseDTO = ResponseDTO(...) // 初始化你的响应DTO实例 `when`(mockWebClient.post()).thenReturn(requestBodyUriMock) `when`(requestBodyUriMock.uri(uri)).thenReturn(requestBodyMock) `when`(requestBodyMock.bodyValue(requestDTO)).thenReturn(requestHeadersMock) `when`(requestHeadersMock.retrieve()).thenReturn(responseMock) `when`(responseMock.bodyToMono(any(Class::class.java))).thenReturn(Mono.just(responseDTO)) val response = webclient.post<ResponseDTO>(uri, requestDTO, ResponseDTO::class.java) assertEquals(responseDTO, response) }
内容的提问来源于stack exchange,提问作者Hamza
相关产品推荐
相关产品推荐

