如何使用 spring boot 和 spock 运行测试容器

Posted

技术标签:

【中文标题】如何使用 spring boot 和 spock 运行测试容器【英文标题】:How to run test Containers with spring boot and spock 【发布时间】:2019-01-27 01:02:01 【问题描述】:

我想在我的 Spring Boot 应用程序中使用带有 spock 的测试容器。

这些是我的依赖:

dependencies 
    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile 'org.testcontainers:spock:1.8.3'
    runtime('org.springframework.boot:spring-boot-devtools')
    compile 'org.codehaus.groovy:groovy-all:2.4.15'
    compileOnly('org.projectlombok:lombok')

    compile 'org.testcontainers:testcontainers:1.8.3'
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile "org.spockframework:spock-core:1.1-groovy-2.4-rc-4"
    testCompile "org.spockframework:spock-spring:1.1-groovy-2.4-rc-4"
    testCompile 'com.github.testcontainers:testcontainers-spock:-SNAPSHOT'

我已经像下面这样初始化了我的测试:

@SpringBootTest
@Testcontainers
class ProductRedisRepositoryTest extends Specification 

    @Autowired
    ProductRedisRepository productRedisRepository

    @Autowired
    TestComponent testComponent


    static Consumer<CreateContainerCmd> cmd =  -> e.withPortBindings(new PortBinding(Ports.Binding.bindPort(6379), new ExposedPort(6379)))

    @Shared
    public static GenericContainer redis =
            new GenericContainer("redis:3.0.2")
                    //.withExposedPorts(6379)
                    .withCreateContainerCmdModifier(cmd)

    def "check redis repository save and get"()

        given:
            Product product = Product.builder()
                    .brand("brand")
                    .id("id")
                    .model("model")
                    .name( "name")
                    .build()
        when:
            productRedisRepository.save(product)
            Product persistProduct = productRedisRepository.find("id")

        then:
            persistProduct.getName() == product.getName()
    


但是当我运行测试时它不会启动 redis 容器。 我的错误是什么。我该怎么做。

我的 springBootVersion = '2.0.4.RELEASE' 我正在使用 Intelij。

这是日志输出:LOG

【问题讨论】:

可以提供日志输出吗? 请考虑将compile 'org.testcontainers:spock...' 更改为testCompile 'org.testcontainers:spock...'。您还可以删除过时的testCompile 'com.github.testcontainers:testcontainers-spock...' 行。 @gesellix 我照你说的做了,但结果还是一样。我在帖子末尾添加了日志输出。 另一个错字:请将 -&gt; e.withPortBindings ... 更改为 e -&gt; e.withPortBindings ...。或者更简单的是 it.withPortBindings ... 【参考方案1】:

请删除@Shared GenericContainer 字段中的static 关键字。

Spock 框架不会用@FieldMetadata 注释静态字段,因此它们不会被视为规范字段的一部分。 Testcontainers-Spock 依靠这些字段来识别 GenericContainers。

如果你需要 static 修饰符,你可以像这样解决这个问题:

...

public static GenericContainer staticRedis =
        new GenericContainer("redis:3.0.2")
                //.withExposedPorts(6379)
                .withCreateContainerCmdModifier(cmd)

@Shared
public GenericContainer redis = staticRedis

...

【讨论】:

以上是关于如何使用 spring boot 和 spock 运行测试容器的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Boot 应用程序和 Spock 测试在运行时更改服务器端口

使用属性 server.port=0 运行 spock 测试时如何找到 Spring Boot 容器的端口

Spock 和 Spring Boot 集成测试

在Spring Boot项目中使用Spock测试框架

使用带有 Spring Boot 的 Spock 测试框架来测试我的 REST 控制器

spring boot单元测试之druid NullPointException问题解决