用 H2 做集成测试为什么不放心?Testcontainers 要写多少配置?容器端口怎么办?两个测试类要不要各起一个容器?这篇在本机的 Docker 上起真实的 MySQL 8.4 和 Redis 7,逐项实测。
[T1] 从测试类初始化到测试方法开始(含启动 MySQL 容器、等它就绪、建 Spring 上下文)用了 6874 ms [T1] 容器:mysql:8.4,容器 id ec4b8a1472dd,JDBC URL jdbc:mysql://localhost:56365/test [T1] docker ps(带 testcontainers 标签):mysql:8.4 0.0.0.0:56365->3306/tcp, [::]:56365->3306/tcp [T1] select version() → 8.4.11 [T1] MySQL:where name = 'ABC' 命中 1 行(存的是 abc) [T1] H2 内存库:同样的 SQL 命中 0 行 [T1] H2:INSERT … ON DUPLICATE KEY UPDATE 失败:Syntax error in SQL statement "insert into u values (1, 2) [*]on duplicate key update v = [T1] MySQL:INSERT … ON DUPLICATE KEY UPDATE 之后 v = 2 退出码 0;成功 1,失败 0;整条命令 11959 ms 测试结束后带 testcontainers 标签的容器:(没有)
@Container 加 @ServiceConnection 不用写连接信息;端口随机映射;内存库与 MySQL 在大小写比较和 ON DUPLICATE KEY 上行为不同。
[T2] 容器:redis:7-alpine,容器 id 7ef4296ea928,映射端口 6379 → 56424 [T2] set / get → v;ttl 100 秒 退出码 0;成功 1,失败 0;整条命令 2472 ms 测试结束后带 testcontainers 标签的容器:(没有)
GenericContainer 加 @ServiceConnection(name = "redis"),起得很快。
各自 @Container(static 字段): [P1] 自己的容器 id 93d64966ceb3;select 1 → 1 [P2] 自己的容器 id 57e1b27d60cc;select 1 → 1 退出码 0;成功 2,失败 0;整条命令 16949 ms 各自 @Container(static 字段):3 次整条命令中位 16949 ms(范围 16721~16983) 共用 @TestConfiguration 里的 @Bean @ServiceConnection 容器(两个类 @Import 同一个配置,共用 Spring 上下文缓存): [Q1] 共用的容器 id 487bfe748ed3;select 1 → 1 [Q2] 共用的容器 id 487bfe748ed3;select 1 → 1 退出码 0;成功 2,失败 0;整条命令 7476 ms 共用 @TestConfiguration 里的 @Bean @ServiceConnection 容器(两个类 @Import 同一个配置,共用 Spring 上下文缓存):3 次整条命令中位 7476 ms(范围 7358~7597) 对比:各自容器 16949 ms,共用容器 7476 ms
把容器放进 @Bean + @ServiceConnection 并在多个测试类里 @Import,可以共用同一个容器,省掉重复启动。