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

如何为返回Listener的gRPC拦截器函数编写测试

gRPC服务端拦截器测试方案

测试核心逻辑

你提供的拦截器功能是:在服务端调用sendHeaders返回响应头前,自动写入自定义头CUSTOM_HEADER_KEY,值为customRespondValue。测试只需要验证这个逻辑触发时的头写入行为即可,不需要启动真实的gRPC服务。

测试前置准备

需要用到以下工具:

  • 单元测试框架(比如ScalaTest、JUnit)
  • Mock框架(比如Mockito,用来mock gRPC的核心接口,避免真实服务启动)

完整测试代码示例

import io.grpc.{Metadata, ServerCall, ServerCallHandler, ServerCallListener}
import org.mockito.Mockito._
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
import org.scalatestplus.mockito.MockitoSugar

// 假设你的拦截器类名为CustomHeaderServerInterceptor
class CustomHeaderServerInterceptorTest extends AnyWordSpec with Matchers with MockitoSugar {
  // 和实现代码里的自定义头常量保持一致
  val CUSTOM_HEADER_KEY: Metadata.Key[String] = Metadata.Key.of("your-custom-header-name", Metadata.ASCII_STRING_MARSHALLER)
  val interceptor = new CustomHeaderServerInterceptor()

  "CustomHeaderServerInterceptor" should {
    "add expected custom header to response headers when sendHeaders is called" in {
      // 1. Mock所有依赖的gRPC接口
      val mockCall = mock[ServerCall[String, String]]
      val requestHeaders = new Metadata()
      val mockNextHandler = mock[ServerCallHandler[String, String]]
      val mockListener = mock[ServerCall.Listener[String]]
      
      // 2. 配置mock逻辑:当nextHandler调用startCall时返回我们mock的Listener
      when(mockNextHandler.startCall(any(classOf[ServerCall[String, String]]), any(classOf[Metadata])))
        .thenReturn(mockListener)

      // 3. 执行拦截器的interceptCall方法
      val resultListener = interceptor.interceptCall(mockCall, requestHeaders, mockNextHandler)
      
      // 4. 捕获next.startCall传入的包装后的ServerCall实例
      val captor = argumentCaptor[ServerCall[String, String]]
      verify(mockNextHandler).startCall(captor.capture(), any(classOf[Metadata]))
      val wrappedCall = captor.getValue

      // 5. 构造测试用响应头,主动调用sendHeaders模拟服务端返回头的场景
      val testResponseHeaders = new Metadata()
      wrappedCall.sendHeaders(testResponseHeaders)

      // 6. 验证自定义头正确写入,同时原有逻辑没有被破坏
      testResponseHeaders.get(CUSTOM_HEADER_KEY) shouldBe "customRespondValue"
      verify(mockCall).sendHeaders(testResponseHeaders)
      resultListener shouldBe mockListener
    }
  }
}

扩展说明

如果你的拦截器还有其他逻辑,比如请求头校验、异常处理、响应内容修改等,可以按照同样的思路,对应模拟触发对应方法,验证输出结果符合预期即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:30:05