Giriş
Şu satırı dahil ederiz
import org.testcontainers.containers.MySQLContainer;
Maven
Şu satırı dahil ederiz
<dependency> <groupId>org.testcontainers</groupId> <artifactId>mysql</artifactId> <version>1.18.0</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> <scope>test</scope> </dependency>
Gradle
Şu satırı dahil ederiz
implementation platform('org.testcontainers:testcontainers-bom:1.16.3') //import bomtestImplementation ('org.testcontainers:junit-jupiter') //no version specifiedtestImplementation('org.testcontainers:mysql') //no version specifiedtestImplementation 'mysql:mysql-connector-java:8.0.27'
Genel Kullanım
Bir ara benim ortamımdaki MySQLContainer sebepsiz yere çalışmamaya başladı. Daha sonra withTmpFs() ile kullanınca düzedi. Şöyle yaparız
MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0.32") .withUsername(...) .withPassword(...) .withLogConsumer(new Slf4jLogConsumer(LOGGER).withPrefix("Docker")) .withTmpFs(Map.of("/var/lib/mysql/", "rw", "/tmp/", "rw" ));
By default, MySQL stores database files in /var/lib/mysql.
DataSource İle Kullanım
1. com.mysql.cj.jdbc.MysqlDataSource İle Kullanımı
Örnek
En basit örnek şöyle. Bazı işleri kolaylaştıracak bir sınıfım olsun. Böylece hem docker image ismini, hem de veri tabanı ismini kolayca belirtirim
import org.testcontainers.containers.MySQLContainer; public class CustomMySqlContainer extends MySQLContainer<CustomMySqlContainer> { private static final String DB_IMAGE = "mysql:8.0.11"; public CustomMySqlContainer() { super(DB_IMAGE); withDatabaseName("ADV"); } }
Test içinde şöyle yaparız
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import com.mysql.cj.jdbc.MysqlDataSource; @Testcontainers class FooTest { // will be shared between test methods @Container private static final CustomMySqlContainer container = new CustomMySqlContainer() .withInitScript("database/functions.sql"); private static DataSource dataSource; @BeforeAll public static void setUp() { MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl(container.getJdbcUrl()); dataSource.setUser(container.getUsername()); dataSource.setPassword(container.getPassword()); FooTest.dataSource = dataSource; } @Test void truncateTable() throws SQLException { try (Connection connection = dataSource.getConnection()) { ... } } }
2. Hikari İle Kullanımı
Örnek
Şöyle yaparız. Burada MySQLContainer sınıfının getJdbcUrl(), getUsername(), getPassword() gibi metodları kullanılıyor
@Testcontainers class HikariDataSourceTest { // will be shared between test methods @Container MySQLContainer container = (MySQLContainer) new MySQLContainer("mysql:8.0.11") .withDatabaseName("ADV") .withInitScript("database/hikaridatasource.sql"); @Test void localHikariDataSource() throws SQLException { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setJdbcUrl(container.getJdbcUrl()); hikariConfig.setUsername(container.getUsername()); hikariConfig.setPassword(container.getPassword()); try (HikariDataSource hikariDataSource = new HikariDataSource(hikariConfig)) { try (Connection connection = hikariDataSource.getConnection()) { try (PreparedStatement preparedStatement = connection.prepareStatement("...")) { try (ResultSet resultSet = preparedStatement.executeQuery()) { while (resultSet.next()) { String string = resultSet.getString(1); System.out.println(string); } } } } } } }
Metodlar
stop metodu
Container bir kere durdurulduktan sonra yeniden başlatılırsa yepyeni bir veri tabanı yaratılıyor. Dolayısıyla bu yeni URL ile JDBC connection almak gerekiyor. Açıklaması şöyle
Right now if you just stop() container, than it will be deleted immediately afterward.
Örnek
Şöyle yaparız
private static final MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0.11"); @Test public void foo() throws SQLException { mysql.start(); String jdbcUrl = mysql.getJdbcUrl(); String username = mysql.getUsername(); String password = mysql.getPassword(); // Success try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) { ... } mysql.stop(); // Throws exception try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) { ... } catch (Exception exception) { ... } // Start again mysql.start(); jdbcUrl = mysql.getJdbcUrl(); username = mysql.getUsername(); password = mysql.getPassword(); // No exception try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) { ... } catch (Exception exception) { ... } }
Örnek
Ben bunu çalıştıramadım ama bu yazıya göre container'ı silmeden yani remove etmeden durdurma şöyle
@Testcontainers public class SomeClass { @Test void stopAndStartContainer() { try ( Network network = Network.newNetwork(); GenericContainer<?> nginx = new GenericContainer("nginx:latest") .withNetwork(network) .withNetworkAliases("foo") ) { nginx.start(); // starting UI // ..... // doint some stuff with UI DockerClient client = DockerClientFactory.lazyClient(); client.stopContainerCmd(nginx.getContainerId()).exec(); // asserting reconnection pooling behaviour on UI client.startContainerCmd(nginx.getContainerId()).exec(); // asserting successful reconnection behaviour on UI } } }
withInitScript metodu
Örnek
Şöyle yaparız
private static final MySQLContainer mySQLContainer = new MySQLContainer<>("mysql:8.0.30") .withDatabaseName("testcontainer") .withUsername("user") .withPassword("pass") .withInitScript("init.sql");
test/java/resources/init.sql şöyledir
CREATE TABLE tests ( id BIGINT AUTO_INCREMENT PRIMARY KEY );
withLogConsumer metodu
Örnek
Şöyle yaparız
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testcontainers.containers.output.Slf4jLogConsumer; private static final Logger logger = LoggerFactory.getLogger(SimpleMySQLTest.class); public static final String USERNAME = "mysql"; public static final String PASSWORD = "mysql"; private static final MySQLContainer<?> mysql = new MySQLContainer<>("mysql:5.7.34") .withUsername(USERNAME) .withPassword(PASSWORD) .withLogConsumer(new Slf4jLogConsumer(LOGGER).withPrefix("Docker"));
withUrlParam metodu
getJdbcUrl() çağrısı yapılınca döndürülecek URL String'ini ayarlamak içindir.
Örnek
Şöyle yaparız. MySQLContainer root kullanıcı yaratmaya izin veriyor
MySQLContainer<?> container = new MySQLContainer<>("mysql:8.0.32") .withDatabaseName("mydb") .withUsername("root") .withUrlParam("user", "root") .withUrlParam("password", "test");
withReuse metodu
Örnek
Şöyle yaparız
public abstract class BaseIT { // ... @ServiceConnection private static final MySQLContainer mySQLContainer = new MySQLContainer("mysql:8.0"); static { mySQLContainer.withUrlParam("serverTimezone", "UTC") .withReuse(true) .start(); } }
Hiç yorum yok:
Yorum Gönder