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

Spring Boot测试中用Wiremock/MockServer返回响应时更新嵌入式数据库

问题原因

你使用withCallbackClass注册回调时,MockServer会通过无参构造自行反射创建回调类实例,该实例不受Spring上下文管理,@Autowired注解不会生效,因此jdbcTemplate为null。MockServer默认会吞噬回调方法抛出的异常,因此你只会观察到更新语句不生效,不会收到空指针报错。

解决方案

方案1:传入Spring托管的回调实例(推荐)

  1. 将回调类改为Spring组件,通过构造函数注入依赖
@Component
public class ApprovalHappyPathCallback implements ExpectationResponseCallback {
    private final JdbcTemplate jdbcTemplate;

    public ApprovalHappyPathCallback(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    public static final HttpResponse httpResponse = response()
            .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
            .withHeaders(
                    header("x-callback", "test_callback_header"),
                    header("Content-Length", "a_callback_response".getBytes(UTF_8).length),
                    header("Connection", "keep-alive")
            )
            .withBody("a_callback_response");

    @Override
    public HttpResponse handle(HttpRequest httpRequest) {
        if (httpRequest.getMethod().equals("GET")) {
            jdbcTemplate.execute("update communications set status = 'APPROVED_SCHEDULED' where id = 153511");
            return httpResponse;
        } else {
            return notFoundResponse();
        }
    }
}
  1. 在测试类中注入该回调实例,注册时使用withCallbackObject代替withCallbackClass
@Autowired
private ApprovalHappyPathCallback approvalHappyPathCallback;

// 注册Mock规则
mockServer.when(request().withMethod("GET"))
        .withBody("Approved")
        .respond(
            callback()
                .withCallbackObject(approvalHappyPathCallback)
        );

方案2:直接在测试类内编写回调逻辑(更轻量)

无需单独创建回调类,直接在测试类中使用注入的JdbcTemplate编写回调:

@Autowired
private JdbcTemplate jdbcTemplate;

// 注册Mock规则
mockServer.when(request().withMethod("GET").withBody("Approved"))
        .respond(httpRequest -> {
            if ("GET".equals(httpRequest.getMethod())) {
                jdbcTemplate.execute("update communications set status = 'APPROVED_SCHEDULED' where id = 153511");
                return response()
                        .withStatusCode(HttpStatusCode.ACCEPTED_202.code())
                        .withHeaders(
                                header("x-callback", "test_callback_header"),
                                header("Content-Length", "a_callback_response".getBytes(StandardCharsets.UTF_8).length),
                                header("Connection", "keep-alive")
                        )
                        .withBody("a_callback_response");
            }
            return notFoundResponse();
        });
注意事项
  • 若测试用例添加了@Transactional注解,默认会在测试结束后回滚所有数据库操作,回调执行的更新也会被回滚,符合单测隔离要求
  • 不建议写死数据库记录ID,可通过ThreadLocal存储测试用例生成的动态ID,在回调中读取使用,提升测试用例通用性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 01:51:03