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

使用ContentCachingResponseWrapper的签名Filter如何编写Mockito单元测试

问题根因

你在自定义Servlet的doPost方法中,没有使用方法入参传入的resp对象写入响应,而是直接写入了外部声明的原始MockHttpServletResponse res。
Filter执行chain.doFilter时传入的是自身包装好的ContentCachingResponseWrapper实例,也就是doPost方法的resp入参,你绕开包装实例直接写原始响应,ContentCachingResponseWrapper自然捕获不到任何内容。

修正后的测试代码
@ExtendWith(MockitoExtension.class)
class ResponseSignerFilterTest {
  @Test
    void exampleTest() throws ServletException, IOException {
        final ResponseSignerFilter filter = new ResponseSignerFilter(appPrivateKey, getJwtSettings());
        final MockHttpServletRequest req = new MockHttpServletRequest();
        req.setMethod("POST");
        final MockHttpServletResponse res = new MockHttpServletResponse();
        res.setContentType("application/json");
        final MockFilterChain filterChain = new MockFilterChain(new HttpServlet() {
            @Override
            protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
                // 必须使用入参的resp对象写入,这是Filter传入的包装实例
                resp.getWriter().write("test-body");
                // 也可以用流写入:resp.getOutputStream().write("test-body".getBytes(StandardCharsets.UTF_8));
            }
        });
        filter.doFilter(req, res, filterChain);
        // 执行断言逻辑,比如:
        String responseContent = res.getContentAsString(StandardCharsets.UTF_8);
        // 验证响应内容、签名头等
    }
}
额外注意点
  • 不要在测试逻辑中主动调用setCommitted(true),ContentCachingResponseWrapper需要在签名计算完成后才将缓存内容写回原始响应,提前标记响应为已提交会导致写回失败
  • 不需要手动设置contentLength,包装类会自动根据缓存的内容长度处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:54:05