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

