如何验证/测试WebClient使用情况

jos*_*ste 5 spring-webflux

我需要对使用的类进行单元测试WebClient。有什么好的方法来处理WebClient吗?有了RestTemplateI,我可以轻松使用Mockito。模拟WebClient有点乏味,因为深度存根无法与WebClient一起使用...

我想测试我的代码是否提供正确的标题...缩短的示例代码:

public class MyOperations {
    private final WebClient webClient;

    public MyOperations(WebClient webClient) {
        this.webClient = webClient;
    }

    public Mono<ResponseEntity<String>> get( URI uri) {
        return webClient.get()
                        .uri(uri)
                        .headers(computeHeaders())
                        .accept(MediaType.APPLICATION_JSON)
                        .retrieve().toEntity(String.class);
    }

    private HttpHeaders computeHeaders() {
        ...
    }

}
Run Code Online (Sandbox Code Playgroud)

小智 5

这是针对单元,而不是集成测试......

Kotlin 中实现,这有点初级,但很有效。这个想法可以从下面的这段代码中提取出来

一、一个WebClient kotlin扩展

import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mockito.*
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.reactive.function.client.WebClientResponseException
import reactor.core.publisher.toMono

fun WebClient.mockAndReturn(data: Any) {
    val uriSpec = mock(WebClient.RequestBodyUriSpec::class.java)
    doReturn(uriSpec).`when`(this).get()
    doReturn(uriSpec).`when`(this).post()
    ...

    val headerSpec = mock(WebClient.RequestBodyUriSpec::class.java)
    doReturn(headerSpec).`when`(uriSpec).uri(anyString())
    doReturn(headerSpec).`when`(uriSpec).uri(anyString(), anyString())
    doReturn(headerSpec).`when`(uriSpec).uri(anyString(), any())
    doReturn(headerSpec).`when`(headerSpec).accept(any())
    doReturn(headerSpec).`when`(headerSpec).header(any(), any())
    doReturn(headerSpec).`when`(headerSpec).contentType(any())
    doReturn(headerSpec).`when`(headerSpec).body(any())

    val clientResponse = mock(WebClient.ResponseSpec::class.java)
    doReturn(clientResponse).`when`(headerSpec).retrieve()
    doReturn(data.toMono()).`when`(clientResponse).bodyToMono(data.javaClass)
}

fun WebClient.mockAndThrow() {
    doThrow(WebClientResponseException::class.java).`when`(this).get()
    doThrow(WebClientResponseException::class.java).`when`(this).post()
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后,单元测试

class MyRepositoryTest {

    lateinit var client: WebClient

    lateinit var repository: MyRepository

    @BeforeEach
    fun setUp() {
        client = mock(WebClient::class.java)
        repository = MyRepository(client)
    }

    @Test
    fun getError() {
        assertThrows(WebClientResponseException::class.java, {
            client.mockAndThrow()
            repository.get("x")
        })
    }

    @Test
    fun get() {
        val myType = MyType()
        client.mockAndReturn(myType)
        assertEquals(myType, repository.get("x").block())
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:在 JUnit 5 上进行测试


Bri*_*zel 1

这将在未来的 Spring 框架版本中得到支持MockRestServiceServer;参见SPR-15286

  • 不幸的是它不会。此问题已结束,请注意您可以使用 [OkHttp MockWebServer](https://github.com/square/okhttp#mockwebserver)。但我认为 [WireMock](http://wiremock.org/) 更好。 (3认同)