当前位置: 首页 > 知识库问答 >
问题:

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

宫修贤
2023-03-14

我需要对使用WebClient的类进行单元测试。有什么好方法来处理网络客户端吗?有了RestTemplate,我可以很容易地使用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() {
        ...
    }

}

共有2个答案

祁正阳
2023-03-14

这将在MockRestServiceServer的未来Spring Framework版本中得到支持;请参阅SPR-15286

终育
2023-03-14

这是为了单元测试,而不是集成测试。。。

在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()
    ...
}

然后,单元测试

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())
    }
}

注:JUnit 5上的测试

 类似资料:
  • 我需要测试验证注释,但看起来它们不起作用。我不确定JUnit是否也是正确的。目前,测试将通过,但您可以看到指定的电子邮件地址是错误的。 JUnit 待测试类别

  • 问题内容: 我正在使用Passport.js进行身份验证(本地策略),并通过Mocha和Supertest进行测试。 如何使用Supertest创建会话并发出经过身份验证的请求? 问题答案: 您应该为此使用超级代理。它是较低级别的模块,由。看一看持久代理: 现在,您可以用来发出经过身份验证的请求。

  • 我们正在慢慢地将一些项目从使用遗留的RestTemplate类迁移到新的Spring 5 WebClient。作为其中的一部分,我们有一些现有的测试类,这些测试类使用Mockito来验证给定的方法是否会使用模板对endpointX进行GET/POST/whatever。 考虑到WebClient的流畅界面,同样的模拟方法实际上并不实用。我花了一些时间使用WireMock,这很好,但不幸的是,似乎有

  • 因此,应用程序流程如下: Spring应用程序接收请求- 这是我正在使用的网络客户端(副本): 现在我不想通过控制器将此Mono对象直接返回到客户端(如Angular应用程序),因为这是一个中间步骤。我想对从 WebClient 收到的响应运行一些验证。 我已经试过<代码>。block()方法来检索函数,但是按照反应式编程,这似乎是一种不好的做法。(阻塞操作)此外,我无法理解如何使用<代码>。su

  • > 列表项 我的日期验证代码块: 我的单元测试:因为dateformat为空,所以第一行出现错误。我如何修复它? 我应该如何使用assert函数,条件应该是什么?

  • 我在JavaFX应用程序上通过hibernate-validation使用Java Beans验证,因此,没有框架来帮助连接。我将这些依赖项添加到我的项目中: 我发现这可以使<code>modelObject</code>得到验证: 我的问题是,每次验证时都创建一个新的工厂和验证器不好吗?我应该将它们缓存在某个地方并重复使用它们吗?验证器有多昂贵和多线程?