【问题标题】:Why does Spring Boot spawn 2 test containers with singleton container approach?为什么 Spring Boot 使用单例容器方法生成 2 个测试容器?
【发布时间】:2021-10-28 02:16:06
【问题描述】:

我正在使用带有 Junit 5 的 Spring-boot 2.5.3

我正在尝试使用 PostgresSQL 测试容器进行测试。我需要将同一个测试容器用于集成测试和存储库测试,因为它在 Docker 中有两个实例。

这是我初始化容器的基类。

import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;

public  class PostgresTestContainer {
    static final PostgreSQLContainer postgreSQLContainer;

    static {
        postgreSQLContainer = (PostgreSQLContainer) new PostgreSQLContainer("postgres:12")
                .withDatabaseName("test")
                .withUsername("postgres")
                .withPassword("postgres")
                .withReuse(true);

        postgreSQLContainer.start();
    }

    @DynamicPropertySource
    static void datasourceConfig(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
        registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
        registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
    }
}

这是存储库测试。

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class CustomerRepositoryTest extends PostgresTestContainer {

    @Autowired
    private CustomerRepository customerRepository;

    @Test
    @Sql("/scripts/import.sql")
    public void findAllShouldGetAllCustomers() {
        List<Customer> foundCustomers = customerRepository.findAll();
        assertThat(foundCustomers).isNotNull();
        assertThat(foundCustomers.size()).isEqualTo(3);
    }
}

这是另一个我需要使用相同测试容器的地方。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BasicIT extends PostgresTestContainer {
    @Autowired
    private TestRestTemplate testRestTemplate;

    @MockBean
    private CustomerRepository customerRepository;

    @Test
    void shouldFailFetchingCustomersWhenDatabaseIsDown() {
        when(customerRepository.findAll()).thenThrow(new RuntimeException("Cannot connect to database."));
        ResponseEntity<String> result = this.testRestTemplate
                .exchange("/api/v1/customers", HttpMethod.GET, HttpEntity.EMPTY, String.class);
        assertEquals(500, result.getStatusCodeValue());
    }


    @Test
    public void shouldFetchAListOfCustomers(){
        ResponseEntity<List<Customer>> result = this.testRestTemplate
                .exchange("/api/v1/customers", HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference<>() {});
        assertEquals(200, result.getStatusCodeValue());
    }
}

跑步:

mvn clean install

这可行,所有测试都会运行。

但它会打开两个容器,如此处的 Docker 映像所示。

如何正确使用单例容器?我只想使用一个。

【问题讨论】:

    标签: java spring-boot spring-boot-test testcontainers


    【解决方案1】:

    从容器镜像名称可以看出,容器是不同的。第二个容器是您的数据库 (postgres),但第一个容器 (ryuk) 是一个辅助容器,默认情况下由 Testcontainer 库本身启动。 Ryuk 对不再需要的其他容器 (documentation) 执行故障安全清理。无需担心,因为它很小 (~5Mb)。

    如果您绝对确定不需要它,您可以在this instruction 之后禁用ryuk

    【讨论】:

      猜你喜欢
      • 2021-10-19
      • 2022-10-04
      • 2019-09-16
      • 2015-04-15
      • 2019-12-10
      • 1970-01-01
      • 2019-01-27
      • 1970-01-01
      • 2021-09-05
      相关资源
      最近更新 更多