在 SpringBoot 中使用 Testcontainers 进行 Spring Data Elasticsearch 集成测试

问题描述

我正在尝试使用 Testcontainers 和 junit5 为 SpringBoot 中的 Spring Data Elastisearch 存储库编写集成测试。但是测试失败了

org.springframework.beans.factory.UnsatisfiedDependencyException: 创建带有名称的 bean 时出错 'com.example.demo.AddressRepositoryTest':不满意的依赖 通过字段“存储库”表示;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:否 'com.example.demo.AddressRepository' 类型的合格 bean 可用:预计至少有 1 个符合自动装配条件的 bean 候选人。依赖注解: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

我该如何解决这个问题?我尝试使用谷歌搜索但找不到任何合适的内容。

DTO

@Data
@Document(indexName = "addresses")
public class Address {
    String city;
    String street;
    GeoJsonPoint location;
}

存储库

@Repository
public interface AddressRepository extends ElasticsearchRepository<Address,String> {

}

测试 AddressRepositoryTest.java

@ExtendWith(SpringExtension.class)
@Testcontainers
class AddressRepositoryTest {

    private static final String ELASTICSEARCH_VERSION = "7.10.1";

    static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(final ConfigurableApplicationContext configurableApplicationContext) {

        }
    }

    @Container
    public static ElasticsearchContainer container = new ElasticsearchContainer(DockerImageName
            .parse("docker.elastic.co/elasticsearch/elasticsearch-oss")
            .withTag(ELASTICSEARCH_VERSION));

    @Autowired
    AddressRepository repository;

    @Autowired
    private Config esConfig;

    @BeforeEach
    void setUp() {
        container.start();
        System.setProperty("elasticsearch.host",container.getContainerIpAddress());
        System.setProperty("elasticsearch.port",String.valueOf(container.getMappedPort(9300)));
        assertTrue(container.isRunning());
    }

    @AfterEach
    void tearDown() {
        container.stop();
    }

    @Test
    void save() {
        final Address address = new Address();
        address.setCity("Some city");
        address.setStreet("Some street");

        address.setLocation(GeoJsonPoint.of(0,0));
        final Address save = repository.save(address);

    }
}

解决方法

在 Spring 中,你必须以某种方式初始化一个上下文,否则没有什么可以自动装配的。它通常使用 @Import 注释完成,您可以在其中设置特定配置,或者使用 @SpringBootTest 注释(在这种情况下,您不需要 @ExtendWith),如果这是一个测试。

请在谷歌上搜索“spring boot test”或“spring boot test jpa”。也许像 - https://www.baeldung.com/spring-boot-testing

因为上下文不是默认创建的,所以没有什么可以自动装配的。 @ExtendWith(SpringExtension.class) 不创建上下文。在生产应用程序中,@SpringBootApplication 这样做,对于测试,有一个 @SpringBootTest 替代方案。

我还建议读一本书,Spring in action,前两章可能就够了。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...