如何在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
相关产品推荐
相关产品推荐

