我有一个Spring Boot应用,使用spock
和testcontainers
(mysql)编写测试。我所做的工作正常,但是感觉不正确(因为@sql
会在每次测试迭代中都进行,所以我必须在SQL脚本中使用INSERT IGNORE ...
。我也不满意静态和非静态mysqlcontainer的技巧)。
我是测试容器(实际上是spock)的初学者,所以如果有人可以告诉我如何使用spock
,@sql
,数据源和testcontainers
使其变得更好,我将不胜感激
@SpringBootTest
@ContextConfiguration(initializers = Initializer.class)
@Testcontainers
class GeneratorTest extends Specification {
public static MySQLContainer staticMySQLContainer = new MySQLContainer()
.withDatabaseName("test")
.withUsername("test")
.withPassword("test")
@Shared
public MySQLContainer mySQLContainer = mySQLContainer;
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
void initialize(@NotNull ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues values = TestPropertyValues.of(
"spring.datasource.url=" + staticMySQLContainer.getJdbcUrl(),
"spring.datasource.password=" + staticMySQLContainer.getPassword(),
"spring.datasource.username=" + staticMySQLContainer.getUsername()
)
values.applyTo(configurableApplicationContext)
}
}
@Autowired
private CarService carService
@Autowired
private BikeRepository bikeRepository
@Sql("/testdata/insert_into_cars.sql")
def "validate number of doors"(int carId, int expectedNrOfDoors) {
given:
Car car = carService.getById(carId)
expect:
car.getNrOfDoors() == expectedNrOfDoors
where:
carId || expectedNrOfDoors
1 || 3
2 || 3
3 || 5
}
}
已更新(使用基于jdbc的容器):
关于JDBC-based containers
,我不确定是否设置正确。我已经在application-test.properties
目录中创建了test/resources
。我已经放在那里了:
spring.datasource.url=jdbc:tc:mysql:8.0.12://localhost:3306/shop?createDatabaseIfNotExist=true&serverTimezone=UTC
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
我的测试类如下:
@SpringBootTest
@Testcontainers
@TestPropertySource(locations="classpath:application-test.properties")
class GeneratorTest extends Specification {
@Autowired
private CarService carService
<skipped for brevity>
当我尝试运行测试类时,我不断得到:
2018-11-20 19:10:25.409 2612@DESKTOP-MLK30PF INFO --- [main] [mysql:8.0.12].waitUntilContainerStarted : Waiting for database connection to become available at jdbc:mysql://192.168.99.100:32770/shop using query 'SELECT 1' (JdbcDatabaseContainer.java:128)
2018-11-20 19:12:25.420 2612@DESKTOP-MLK30PF ERROR --- [main] [mysql:8.0.12].tryStart : Could not start container (GenericContainer.java:297)
org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:53)
at org.testcontainers.containers.JdbcDatabaseContainer.waitUntilContainerStarted(JdbcDatabaseContainer.java:129)
at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:292)
跟着
2018-11-20 19:12:25.486 2612@DESKTOP-MLK30PF INFO --- [tc-okhttp-stream-242833949] [mysql:8.0.12].accept : STDERR: 2018-11-20T18:10:44.918132Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.12' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL. (Slf4jLogConsumer.java:32)
2018-11-20 19:12:25.487 2612@DESKTOP-MLK30PF INFO --- [main] [mysql:8.0.12].tryStart : Creating container for image: mysql:8.0.12 (GenericContainer.java:253)
2018-11-20 19:12:25.609 2612@DESKTOP-MLK30PF INFO --- [main] [mysql:8.0.12].tryStart : Starting container with ID: de75c9dafed8032b84cb827bf43a29c1964bfe4e168422272c9310a4803fd856 (GenericContainer.java:266)
2018-11-20 19:12:25.896 2612@DESKTOP-MLK30PF INFO --- [main] [mysql:8.0.12].tryStart : Container mysql:8.0.12 is starting: de75c9dafed8032b84cb827bf43a29c1964bfe4e168422272c9310a4803fd856 (GenericContainer.java:273)
2018-11-20 19:12:25.901 2612@DESKTOP-MLK30PF INFO --- [main] [mysql:8.0.12].waitUntilContainerStarted : Waiting for database connection to become available at jdbc:mysql://192.168.99.100:32772/shop using query 'SELECT 1' (JdbcDatabaseContainer.java:128)
对于mysql版本8
的问题,请看here
更新(已解决):
正如@bsideup指出的那样,基于jdbc的容器是此用例的最佳解决方案。如我上面所述,它工作得很好,但是我不得不将mysql版本从8
更改为更低版本。
答案 0 :(得分:0)
您尝试过:help netrw
吗?
答案 1 :(得分:0)
你可以做
def setupSpec(){ //or use setup(){ if not a @Shared Container
System.getProperties()
.putAll([
"spring.datasource.url" : mySQLContainer...,
"spring.datasource.username": mySQLContainer...,
"spring.datasource.password": mySQLContainer...
])
}
然后您可以摆脱staticMySQLContainer
以及初始化器