首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Testcontainers中使用自定义DB停靠程序映像

在Testcontainers中使用自定义DB停靠程序映像
EN

Stack Overflow用户
提问于 2018-10-24 11:46:15
回答 2查看 2.1K关注 0票数 2

我是测试容器的新手,所以我有个问题。我在Spring/Hibernate上有应用程序。我有停靠图像(h2testbase)和mysql-base (myTestDb)的数据.我用-p 6161:3306在码头上运行这个映像。在test/resources目录中,我有文件application.properties。它包含下一个

代码语言:javascript
复制
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依赖项

代码语言:javascript
复制
<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类

代码语言:javascript
复制
public class TestMySQL extends MySQLContainer {

    public TestMySQL() {
        super();
    }

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

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

因为MySQLContainer使用com.mysql.jdbc.Driver,因此它被废弃了。我的考试(例如)

代码语言:javascript
复制
@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)容器已经启动。它启动了两三次(映射在诸如328 or这样的随机端口上),但随后maven告诉

代码语言:javascript
复制
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的自定义映像的代码示例。提前谢谢你

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

代码语言:javascript
复制
[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)时,它不是启动的,因为已经分配了端口。如果我从脚本中添加数据-它是“无法创建容器”。如果我尝试给它我的图像(h2testbase),再次“无法创建容器”。

EN

回答 2

Stack Overflow用户

发布于 2018-10-24 12:44:49

看来你这里有两个问题。

  1. Docker在随机端口上公开mysql服务器,但您需要一个固定端口。若要修复此问题,可以使用addFixedExposedPort of GenericContainer设置固定端口 公共类TestMySQL扩展了MySQLContainer { public TestMySQL(String dockerImageName) { super(dockerImageName);addFixedExposedPort(6161,MYSQL_PORT);}@重载公共字符串getDriverClassName() {返回"com.mysql.cj.jdbc.Driver";}}
  2. 您可能没有数据库test,具有密码test的用户test,因为它是MySQLContainer中的默认凭据,这会导致您获得的ContainerLaunchException。使用withDatabaseNamewithUsernamewithPassword正确地配置DB和user。 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration( class ={ HibernateConfiguration.class,SecurityConfiguration.class,SecurityInitializer.class,ViewConfiguration.class,ViewInitializer.class}) @WebAppConfiguration public {@ ControllerServiceJTest容器=新TestMySQL("h2testbase") .withDatabaseName("myTestDb") .withUsername("root") .withPassword("admin");@Test public void stationPagination() { Map pag = controllerService.stationPagination(4);Object> == 8;} @Test public void trainPagination() { Map pag = controllerService.trainPagination(1);Assert.assertTrue(((List)pag.get("trains")).size() == 20);} @Test public void switchHelper() {switchHelper+“/2”);}

更新

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

代码语言:javascript
复制
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.1</version>
    </dependency>

并创建具有以下内容的src/test/resources/logback.xml

代码语言:javascript
复制
<?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
票数 0
EN

Stack Overflow用户

发布于 2022-10-26 11:56:14

我也有同样的问题。从MySQLContainer扩展自定义类时,容器似乎会多次启动。在我的例子中,启动了三个mysql容器。当我直接使用MySQLContainer类时,一切正常工作。只启动一个mysql容器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52968195

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档