繁体   English   中英

在Testcontainers中使用自定义DB docker-image

[英]Using custom DB docker-image with Testcontainers

我是Testcontainers的新手,所以我有一个问题。 我在Spring / Hibernate上有应用程序。 我有带有mysql-base(myTestDb)的docker-image(h2testbase)和数据。 我使用-p 6161:3306在docker中运行该映像。 在test / resources目录中,我有文件application.properties。 它包含下一个

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:6161/myTestDb?allowPublicKeyRetrieval=true&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow&&useSSL=false
jdbc.username=root
jdbc.cred=admin
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.format_sql=true

我使用mvn测试-它正在工作。 现在,我想使用Testcontainers运行这些测试。 我添加了pom.xml依赖项

<dependency>
   <groupId>org.testcontainers</groupId>
   <artifactId>testcontainers</artifactId>
   <version>1.9.1</version>
</dependency>

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>mysql</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
</dependency>

我扩展了类MySQLContainer

public class TestMySQL extends MySQLContainer {

    public TestMySQL() {
        super();
    }

    public TestMySQL(String dockerImageName) {
        super(dockerImageName);
    }

    @Override
    public String getDriverClassName() {
        return "com.mysql.cj.jdbc.Driver";
    }
}

cuz MySQLContainer使用com.mysql.jdbc.Driver,并且已弃用。 我的测试(例如)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
        HibernateConfiguration.class,
        SecurityConfiguration.class,
        SecurityInitializer.class,
        ViewConfiguration.class,
        ViewInitializer.class})
@WebAppConfiguration
public class ControllerServiceJTest {

    @ClassRule
    public static TestMySQL  container
            = new TestMySQL("h2testbase");

    @Autowired
    ControllerService controllerService;

    @Test
    public void stationPagination() {
        Map<String, Object> pag = controllerService.stationPagination(4);
        Assert.assertTrue(((List<Station>)pag.get("stations")).size() == 8);
    }

    @Test
    public void trainPagination() {
        Map<String, Object> pag = controllerService.trainPagination(1);
        Assert.assertTrue(((List<Train>)pag.get("trains")).size() == 20);
    }

    @Test
    public void switchHelper() {
        Assert.assertTrue(controllerService.stationSwitchHelper("BLUE").equals(URLs.REDIRECT_DASHSTATION + "/2"));
    }
}

我在撞墙。 如果我使用mvn test,我(通过docker ps)看到该容器已启动。 它启动了两次或三次(并且映射在诸如328xx的随机端口上进行),但是随后maven告诉

org.testcontainers.containers.ContainerLaunchException: Container startup failed
Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
Caused by: org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
Caused by: java.util.concurrent.TimeoutException

我现在应该怎么办? 如何告诉我的测试容器所需的端口(6161)? 如何使用application.properties中的参数? 我找不到在带有数据的DB中使用自定义图像的代码示例。 先感谢您

更新为失败的测试添加完整结果。

[INFO] -------------------------------------------------------

    [INFO]  T E S T S
    [INFO] -------------------------------------------------------
    [INFO] Running ru.javasch.metro.junit.ControllerServiceJTest
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".
    SLF4J: Defaulting to no-operation MDCAdapter implementation.
    SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.
            ?? Checking the system...
            ? Docker version should be at least 1.6.0
            ? Docker environment should have more than 2GB free disk space
    [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 97.189 s <<< FAILURE! - in ru.javasch.metro.junit.ControllerServiceJTest
    [ERROR] ru.javasch.metro.junit.ControllerServiceJTest  Time elapsed: 97.187 s  <<< ERROR!
    org.testcontainers.containers.ContainerLaunchException: Container startup failed
    Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
    Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
    Caused by: org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
    Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
    Caused by: java.util.concurrent.TimeoutException

有一些信息。 我从这里尝试了MySqlContainer的测试(使用我的TestMySql)。 当我使用干净的mysql:5.5图像-都很好。 但是,当我尝试在容器中添加一些修改时(例如addFixedExposedPort),这不是开始,因为已经分配了cuz端口。 如果我从脚本添加数据,则为“无法创建容器”。 如果我要给它我的图像(h2testbase),则再次“无法创建容器”。

看来您在这里有两个问题。

  1. Docker将mysql服务器暴露在一个随机端口上,但是您需要一个固定端口。 要解决此问题,您可以使用GenericContainer的 addFixedExposedPort设置固定端口

     public class TestMySQL extends MySQLContainer { public TestMySQL(String dockerImageName) { super(dockerImageName); addFixedExposedPort(6161, MYSQL_PORT); } @Override public String getDriverClassName() { return "com.mysql.cj.jdbc.Driver"; } } 
  2. 您可能没有数据库test ,用户test和密码test因为它是MySQLContainer中的默认凭据,这会导致您获得ContainerLaunchException 使用withDatabaseNamewithUsernamewithPassword可以正确配置数据库和用户。

     @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { HibernateConfiguration.class, SecurityConfiguration.class, SecurityInitializer.class, ViewConfiguration.class, ViewInitializer.class}) @WebAppConfiguration public class ControllerServiceJTest { @ClassRule public static TestMySQL container = new TestMySQL("h2testbase") .withDatabaseName("myTestDb") .withUsername("root") .withPassword("admin"); @Autowired ControllerService controllerService; @Test public void stationPagination() { Map<String, Object> pag = controllerService.stationPagination(4); Assert.assertTrue(((List<Station>)pag.get("stations")).size() == 8); } @Test public void trainPagination() { Map<String, Object> pag = controllerService.trainPagination(1); Assert.assertTrue(((List<Train>)pag.get("trains")).size() == 20); } @Test public void switchHelper() { Assert.assertTrue(controllerService.stationSwitchHelper("BLUE").equals(URLs.REDIRECT_DASHSTATION + "/2")); } } 

更新

要打开日志记录,请将以下依赖项添加到pom.xml

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.1</version>
    </dependency>

并使用以下内容创建src/test/resources/logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>

    <logger name="org.testcontainers" level="DEBUG"/>
</configuration

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM