当前位置: 首页 > 知识库问答 >
问题:

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

墨星鹏
2023-03-14
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
<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>
public class TestMySQL extends MySQLContainer {

    public TestMySQL() {
        super();
    }

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

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

因为使用com.mysql.jdbc.driver的MySQLContainer不推荐使用。我的测试(例如)

@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测试,我看到(通过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

我现在该怎么办?如何告诉我的testcontainer需要的端口(6161)?如何使用application.properties中的参数?我找不到使用自定义图像与数据库和数据的代码示例。事先谢谢你

[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)时,它没有启动,因为已经分配了端口。如果我从脚本中添加数据-它是“Could not create container”。如果我尝试给它我的映像(h2testbase),同样是“Could not create container”。

共有1个答案

祁正浩
2023-03-14

看来你这里有两个问题。

>

  • Docker在一个随机端口上公开mysql server,但您需要一个固定端口。要修复此问题,可以使用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";
        }
    }
    

    您可能没有数据库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"));
        }
    }
    
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.1</version>
        </dependency>
    
    <?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
    

  •  类似资料:
    • 如果我把thread.sleep(..)它也有效,但不是更好的解决方案。 什么是正确的解决方案等待或正确的策略知道容器是准备好的?

    • 问题内容: 我正在尝试在使用wkhtmltopdf生成的PDF中使用自定义字体。我读到您不能使用google webfonts,而wkhtmltopdf使用truetype .ttf文件。谁能确认?因此,我从Google webfont下载了一个.ttf文件,并将其放入服务器中,然后使用了字体: 和字体系列: 现在应该以Jolly Lodger字体呈现的文本根本没有出现,页面为空白。 我究竟做错了

    • 问题内容: 我有一个.bmp图像,我想将其用作GUI的光标。该QCursor文件表明,这是可能的(“要创建自己的位图光标,要么使用QCursor构造函数需要一个位图和一个口罩或需要一个像素图作为参数构造函数”),但我似乎无法得到它在我收到’TypeError:QCursor():当我尝试将建议的模块与位图一起使用时,参数1具有意外的类型’str’时起作用。应该怎么做? 下面是产生上述错误的代码。该

    • 我正在编写一个代码,它取两个点,确定两个点的大小,比较它们,并返回哪个更大。我有我的主类和方法来运行所有的东西,然后还有另一个类点来实现我的接口。但是,我无法使从接口调用的方法正常工作。我的代码是: 当我尝试运行它时,我得到错误“exception in thread”main“java.lang.nullPointerException:不能调用”point.getMetality()“,因为”

    • 我试图创建一个音频捕获活动,所以我从android文档中复制了这个类,如下所示 在我的xml页面中,我试图创建一个id为麦克风的RecordButton。类似这样的东西 现在,当我尝试运行该应用程序时,会出现以下输出

    • 我正在使用IText7从html字符串生成pdf。现在,我需要对段落应用自定义颜色和自定义字体或字体系列。 如何使用Itext7实现这一点? 谢谢