mastering testcontainers

src: mastering testcontainers - 2023-02-19

Abstract

  • @DynamicPropertySource to set spring boot properties on integration tests
@DynamicPropertySource
public static void setup(DynamicPropertyRegistry registry) {
  registry.add("spring.redis.host", redis::getHost);
  registry.add("spring.redis.port", redis::getPort);
}
  • Startables.deepStart(redis, kafka).join(); to start multiple containers in parallel
  • postgres tips: add schema file to init the db
static PostgreSQLContainer< ?> postgreSQLContainer = new PostgreSQLContainer<>(
  "postgres:14-alpine"
).withCopyFileToContainer(
  MountableFile.forClasspathResource("/schema.sql"),
  "/docker-entrypoint-initdb.d/"
);
  • @TestContainers in class level will start the @Container fields
    • if field is static, then it will start only once per test class
    • if not `static, then start for each test of the test class
@TestContainers
class FoobarTest {
  @Container
  static KafkaContainer kafka = ...;
}
  • #withReuse(boolean) to not kill the containers after the tests are finished
    • useful for debugging purpose
    • experimental feature
    • can use the same containers by executing the same test
  • can configure the Network to simulate chaos tests:
static Network network = Network.newNetwork();
 
static GenericContainer< ?> redis = new GenericContainer<>("redis:6-alpine")
  .withExposedPort(6379)
  .withNetwork(network)
  .withNetworkAliases("redis");
 
static ToxiproxyContainer toxi = new ToxiproxyContainer("shopify/toxiproxy:2.1.0")
  .withNetwork(network);
 
@DynamicPropertySource
public static void setup(DynamicPropertyRegistry registry) {
  Startables.deepStart(redis, toxi).join();  
 
  var redis1 = toxi.getProxy("redis", 6379);
  registry.add("spring.redis.host", redis1::getContainerIpAddress);
  registry.add("spring.redis.port", redis1::getProxyPort);
 
  redis1.toxics()
    .latency("latency", ToxicDirection.DOWNSTREAM, 2000)
    .setJitter(200);
}