我在我的开放源码软件中使用测试容器,但是我认为在我的配置中或者在坞/测试容器运行时有一个问题.
我有一些测试,当它们分开运行时,一切正常,但是当我尝试运行所有测试时,由于应用程序试图连接容器时出现问题,最后一次测试就会失败。
我发现容器是在一个端口启动的,但是应用程序正在尝试在另一个端口连接,然后大部分在运行的最后一个测试类中使用。
所有正在运行的测试:
其中一个失败的测试向我展示了以下日志:
当类UserControllerTest启动时容器开始使用另一个端口,如下所示:
我的测试配置是基于一个抽象类(请参见下面),并且,就像前面所说的那样,如果运行仅显示错误的类,则一切正常。
@Testcontainers
@ActiveProfiles("test")
@ExtendWith(SpringExtension::class)
@TestMethodOrder(value = OrderAnnotation::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
abstract class AbstractTest {
companion object {
@Container
private val redisContainer = GenericContainer<Nothing>("redis:6-alpine")
.apply {
withExposedPorts(6379)
withCreateContainerCmdModifier { cmd -> cmd.withName("wb-test-cache") }
}
@Container
private val postgresContainer = PostgreSQLContainer<Nothing>("postgres:13-alpine")
.apply {
withExposedPorts(5432)
withUsername("sa_webbudget")
withPassword("sa_webbudget")
withDatabaseName("webbudget")
withCreateContainerCmdModifier { cmd -> cmd.withName("wb-test-database") }
}
@JvmStatic
@DynamicPropertySource
fun dynamicPropertiesRegister(registry: DynamicPropertyRegistry) {
registry.add("spring.datasource.url", postgresContainer::getJdbcUrl)
registry.add("spring.redis.host", redisContainer::getHost)
registry.add("spring.redis.port", redisContainer::getFirstMappedPort)
}
}
}有人见过这样的事,知道怎么解决吗?
发布于 2021-08-31 04:04:13
经过一些研究,我找出了问题所在:背景。
当spring运行第一个mvc控制器测试时,它会对所有控制器启动一个tomcat实例,这意味着当testcontainers重新创建数据库的docker实例时(在一个新的控制器开始测试之后)属性(port,URL.)未更新,因为spring将重用tomcat的当前实例(来自上一次mvc测试)
解决方案:将每个测试类的上下文标记为脏,这将使spring在每次启动新的测试类时重新创建上下文,这将触发dynamicPropertiesRegister以正确更新属性。
我只需要将这个注释@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)添加到我的AbstractTest中
发布于 2021-08-09 03:23:28
您希望启动容器以进行重用。将此应用到一系列方法中:
.withReuse(true);发布于 2021-08-18 15:13:26
根据文件:
声明为静态字段的容器将在测试方法之间共享。它们将在执行任何测试方法之前只启动一次,并在最后一个测试方法执行后停止。声明为实例字段的容器将为每个测试方法启动并停止。
那么,也许您的容器在每次测试时都会重新启动,并获得新的端口号?
请参阅:5/
我们运行一个类似于您想要完成的设置,但是在抽象类中使用一个@ContextConfiguration( initializers = [,其中包含一个初始化器列表,其中配置了每个容器并将其添加到共享ConfigurableApplicationContext中。但是,如果只使用注释就可以使其工作,那么您的方法似乎要简单得多。
https://stackoverflow.com/questions/68660093
复制相似问题