9 Kasım 2022 Çarşamba

SpringTest Testcontainers Kullanımı - TestContainer Sınıfından Kalıtma

Giriş
- Bu kullanım Spring'in @DynamicPropertySource anotasyonunu kullanmadığı için daha çok Spring kullanmayan ama Jupiter ile birim testi yapmak isteyen projeler için daha uygun

- TestContainer başlatıldıktan sonra url, username gibi şeyler System property olarak atanıyor. Böylece spring bunlara erişebiliyor.

Örnek
Şöyle yaparız
import org.testcontainers.containers.OracleContainer;

public class OracleTestContainer extends OracleContainer {

  public static final String DB_CONNECTION_URL = "DB_URL";
  public static final String DB_USERNAME = "DB_USERNAME";
  public static final String DB_PASSWORD = "DB_PASSWORD";
  private static final String IMAGE_VERSION = "oracleinanutshell/oracle-xe-11g:1.0.0";
  private static OracleTestContainer container;

  private OracleTestContainer() {
    super(IMAGE_VERSION);
  }

  public static OracleTestContainer getInstance(String initScriptPath) {
    if (container == null) {
      container = new OracleTestContainer();
      container.withInitScript(initScriptPath);
      container.start();
    }
    return container;
  }

  @Override
  public void start() {
    super.start();
    System.setProperty(DB_CONNECTION_URL, container.getJdbcUrl());
    System.setProperty(DB_USERNAME, container.getUsername());
    System.setProperty(DB_PASSWORD, container.getPassword());
  }
}
Testlerde kullanılacak bir SpringConfig sınıfı tanımlanır. Şöyle yaparız
@ComponentScan(basePackages = {"com.test.app"})
@EnableJpaRepositories(basePackages = "com.test.app")
@EntityScan(basePackageClasses = {RocApplicant.class, ... })
public class ApplicantTestConfig {

}
Soyut bir test sınıfı yaratılır. Şöyle yaparız
@ActiveProfiles("test")
@DataJpaTest
@ContextConfiguration(classes = {ApplicantTestConfig.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Rollback(false)
@EnableAutoConfiguration
public abstract class AbstractTest {

  public static final String INIT_SCRIPT = "sql/test-container-init.sql";

  public static OracleContainer oracle = OracleTestContainer.getInstance(INIT_SCRIPT);

  @BeforeAll
  static void setUp() {
    if (!oracle.isCreated()) {
      oracle.start();
    }
  }
}
Spring'in bağlanabilmesi için application-test.yaml dosyası oluşturulur. Şöyle yaparız
spring:
  datasource:
    driverClassName: oracle.jdbc.OracleDriver
    url: ${DB_URL}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    hikari:
      maximum-pool-size: 2
  test:
    database:
      replace: none
  main:
    allow-bean-definition-overriding: true
  jpa:
    hibernate:
      ddl-auto: none
      database-platform: org.hibernate.dialect.Oracle10gDialect
test sınıfı şöyledir. Burada ilk sql veri tabanını temizler, ikincisi ise doldurur.
class RocApplicantServiceTest extends AbstractTest {
    
  @Autowired
  RocApplicantService mnsRocApplicantService;

  @Test
  @Sql(value = {"classpath:/sql/clean_roc_applicants.sql",
                "classpath:/sql/insert_roc_applicants.sql"})
  void createApplicant() {
    var response = mnsRocApplicantService.createApplicant(...);
    assertNotNull(response);
  }
}


Hiç yorum yok:

Yorum Gönder