10 Şubat 2022 Perşembe

Testcontainers Kullanımı

Giriş
Test Containers iki şekilde kullanılabilir.
1. Using a specially modified JDBC URL. Testcontainers JDBC URL Kullanımı yazısına taşıdım
2. Anotasyonlar ile kullanılır
3. Tüm container'lar GenericContainer sınıfından kalıtır. Bu yüzden GenericContainer yazısına bakmakta fayda var

JUnit 5 Kullanımı
Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.testcontainers</groupId>
  <artifactId>testcontainers</artifactId>
  <scope>test</scope>
</dependency>

<!-- JUnit 5 extension --> 
<dependency>
  <groupId>org.testcontainers</groupId>
  <artifactId>junit-jupiter</artifactId>
  <scope>test</scope>
</dependency>

1. Test sınıfına @TestContainers anotastonu eklenir
2. Teste static veya static olmayan @Generic anotasyonuna sahip bir container eklenir. 
 -- Static ise container tüm testler için bir kere yaratılır, yani paylaşılır. 
-- Static değilse her test için yeni bir container yaratılır

JUnit 4 Kullanımı
JUnit 4 için @Rule/@ClassRule anotayonları kullanılır 

@Testcontainers Anotasyonu
Şu satırı dahil ederiz
import org.testcontainers.junit.jupiter.Testcontainers;
Açıklaması şöyle. Jupiter anotasyonudur. @Container olarak işaretli container'ın start() metodunu çağırır.
Jupiter integration is provided by means of the @Testcontainers annotation.

The extension finds all fields that are annotated with @Container and calls their container lifecycle methods (methods on the Startable interface). Containers declared as static fields will be shared between test methods. They will be started only once before any test method is executed and stopped after the last test method has executed. Containers declared as instance fields will be started and stopped for every test method.

Note: This extension has only been tested with sequential test execution. Using it with parallel test execution is unsupported and may have unintended side effects.

Her Test İçin Yeni Container
Örnek
Şöyle yaparız
private RedisBackedCache underTest;

  @Container
  public GenericContainer redis = new GenericContainer("redis:5.0.8-alpine3.11")
    .withExposedPorts(6379);

  @BeforeEach
  public void setUp() {
    String address = redis.getHost();
    Integer port = redis.getFirstMappedPort();

    underTest = new RedisBackedCache(address, port);
  }

Diğer

Örnek - Testcontainers GCloud Module
Şöyle yaparız
//TestContainers
testImplementation 'org.testcontainers:testcontainers:1.17.3'
testImplementation group: 'org.testcontainers', name: 'junit-jupiter', version: '1.17.3'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.9.0'
implementation 'org.testcontainers:gcloud:1.17.3'
Şöyle yaparız
@Container
private static final SpannerEmulatorContainer spannerEmulatorContainer =
  new SpannerEmulatorContainer(
    DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator:1.1.1"));

//for testing, there is no need to use credentials
@TestConfiguration
static class EmulatorConfiguration {
  @Bean
  NoCredentialsProvider googleCredentials() {
    return NoCredentialsProvider.create();
  }
}

@DynamicPropertySource
static void emulatorProperties(DynamicPropertyRegistry registry) {
  registry.add(
    "spring.cloud.gcp.spanner.emulator-host", 
    spannerEmulatorContainer::getEmulatorGrpcEndpoint);
}
Yardımcı metodlar için şöyle yaparız
private InstanceId createInstance(Spanner spanner) throws InterruptedException, ExecutionException {
  InstanceConfigId instanceConfig = InstanceConfigId.of(PROJECT_ID, "emulator-config");
  InstanceId instanceId = InstanceId.of(PROJECT_ID, INSTANCE_ID);
  InstanceAdminClient insAdminClient = spanner.getInstanceAdminClient();
  Instance instance = insAdminClient
    .createInstance(
      InstanceInfo
        .newBuilder(instanceId)
        .setNodeCount(1)
        .setDisplayName("Test instance")
        .setInstanceConfigId(instanceConfig)
        .build()
       )
   .get();
  return instanceId;
}

private void createDatabase(Spanner spanner) throws InterruptedException, ExecutionException {
  DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient();
  Database database = dbAdminClient
    .createDatabase(
      INSTANCE_ID,
      "order_schema",
      Arrays.asList("CREATE TABLE Orders (orderId INT64 NOT NULL, name STRING(255), order_status STRING(255)) PRIMARY KEY (orderId)")
    )
    .get();
}

private Spanner spanner(){
  SpannerOptions options = SpannerOptions
    .newBuilder()
    .setEmulatorHost(spannerEmulatorContainer.getEmulatorGrpcEndpoint())
    .setCredentials(NoCredentials.getInstance())
    .setProjectId(PROJECT_ID)
    .build();
  Spanner spanner = options.getService();
  return spanner;
}
Test için şöyle yaparız
@Test
public void testOrders() throws ExecutionException, InterruptedException {
    //Create Spanner Instance, DB, Table
    Spanner spanner = spanner();
    InstanceId instanceId = createInstance(spanner);
    createDatabase(spanner);

    //Create Order and Save
    Order order = new Order();
    order.setOrder_status("COMPLETED");
    order.setName("Order1");
    String message = this.orderService.save(order);
    assertEquals("Order Saved Successfully", message);

    //Validate
    List<Order> orders = this.orderService.findOrdersByName("Order1");
    assertTrue(orders.size() == 1);
    assertTrue(orders.get(0).getOrder_status().equals("COMPLETED"));
 }

Hiç yorum yok:

Yorum Gönder