You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Groovy测试的Spring REST调用中验证Reactor上下文值并校验上下文内错误信息

我来帮你解决这两个Reactor上下文相关的Groovy测试问题:

问题1:如何在Groovy测试的Spring REST调用中验证Reactor上下文的值

要在Spring REST调用(比如用WebClient发起的请求)的Groovy测试里验证Reactor上下文,咱们可以借助Reactor Test的StepVerifier工具,步骤如下:

  • 首先确保你的测试依赖里引入了Reactor Test:
    testImplementation 'io.projectreactor:reactor-test'
    
  • 在测试中,先Mock好Spring REST相关的组件(比如WebClient的响应),然后构建带有上下文的数据流
  • 使用StepVerifier订阅数据流,同时在验证环节获取并校验上下文的值

举个简单的示例:

def "verify reactor context in Spring REST call"() {
    given:
    // Mock WebClient的响应(假设你的服务用WebClient调用REST接口)
    def mockResponse = new NameResponse(name: "Test User")
    webClient.get()
        .uri("/api/stud-name/{studNumber}", "123")
        .retrieve()
        .bodyToMono(NameResponse) >> Mono.just(mockResponse)
    
    // 准备预期的上下文内容
    def expectedStudContext = new StudContext(headers, 5000, false)

    when:
    // 调用你的业务方法,该方法内部会使用Reactor上下文
    def resultMono = yourService.fetchMemberDetails("123", new PersonDetail())
        .subscriberContext(Context.of(StudContext.CONTEXT_KEY, expectedStudContext))

    then:
    StepVerifier.create(resultMono)
        .assertNext { personDetail ->
            // 先验证返回的业务结果
            assert personDetail.getName() == "Test User"
            // 获取当前上下文并验证值
            def currentContext = StepVerifier.Step.currentContext()
            def actualStudContext = currentContext.get(StudContext.CONTEXT_KEY)
            assert actualStudContext == expectedStudContext
            assert actualStudContext.getTimeoutMillis() == 5000
        }
        .verifyComplete()
}

如果是Spring MVC的REST接口测试(比如用MockMvc),要确保上下文能正确传递到Reactor流中,可能需要在请求构建时注入上下文,或者在测试配置中启用Reactor上下文的传递支持。

问题2:Groovy测试中获取并校验Reactor上下文中的错误信息(附具体场景)

针对你给出的私有方法和Mock场景,咱们可以这样用StepVerifier验证Reactor上下文中的错误:

步骤1:准备测试环境

首先MockcoreCustomerIndividualNameClient,让它返回预设的错误,同时准备好测试用的StudContext和PersonDetail:

def "verify errors are added to reactor context"() {
    given:
    // 预设要返回的错误
    def testError = new StudError(code: "NAME_FETCH_FAILED", message: "Failed to fetch student name")
    // Mock客户端,让它返回错误
    coreCustomerIndividualNameClient.getStudName(_) >> Mono.error(testError)
    
    // 初始化上下文和PersonDetail
    def studContext = new StudContext(headers, 3000, false)
    def personDetail = new PersonDetail()
    def studNumber = "S12345"

步骤2:调用目标方法并订阅上下文

Groovy允许直接调用私有方法,所以咱们可以直接调用getMemberDetailsWithName,并传入预先准备的上下文:

when:
    def resultMono = yourInstance.getMemberDetailsWithName(studNumber, personDetail)
        .subscriberContext(Context.of(StudContext.CONTEXT_KEY, studContext))

步骤3:用StepVerifier验证上下文错误

在assertNext环节,咱们可以获取当前上下文,取出StudContext并校验错误集合:

then:
    StepVerifier.create(resultMono)
        .assertNext { detail ->
            // 验证返回的PersonDetail符合预期(即使出错也返回原detail)
            assert detail == personDetail
            
            // 获取当前Reactor上下文
            def currentContext = StepVerifier.Step.currentContext()
            // 从上下文中取出StudContext实例
            def actualStudContext = currentContext.get(StudContext.CONTEXT_KEY)
            
            // 校验错误是否被正确添加到上下文的错误集合中
            assert actualStudContext.getErrors().size() == 1
            assert actualStudContext.getErrors().contains(testError)
            assert actualStudContext.getErrors().first().code == "NAME_FETCH_FAILED"
        }
        .verifyComplete()
}

关键注意点

  • 你的代码中handle操作符会从sink.currentContext()获取上下文,所以必须在订阅流时通过subscriberContext传入预设的StudContext,否则会找不到上下文键
  • onErrorResume中收集的错误会在handle环节被添加到上下文的StudContext中,所以测试时要确保Mock的错误被正确捕获并传递

内容的提问来源于stack exchange,提问作者jcrshankar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:37:38