简体   繁体   中英

Spring Data Elasticsearch integration test using Testcontainers in SpringBoot

I am trying out to write an integration test for Spring Data Elastisearch repository in SpringBoot using Testcontainers and junit5. But the test fails with

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.demo.AddressRepositoryTest': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.AddressRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

How could I fix this issue? I tried googling but could not find anything appropriate.

DTO

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

Repository

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

}

The test 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);

    }
}

In Spring you have to initialize a context somehow, otherwise there is nothing to autowire. It's usually either done with @Import annotation where you set a specific config, or a @SpringBootTest annotation (in that case you don't need @ExtendWith ), if that's a test.

Please search google for "spring boot test" or "spring boot test jpa". Maybe something like - https://www.baeldung.com/spring-boot-testing .

It's because context is not created by default that there is nothing to autowire. @ExtendWith(SpringExtension.class) doesn't create a context. In production apps @SpringBootApplication does that, for tests there is a @SpringBootTest alternative.

I would also suggest to read a book, Spring in action, first 2 chapters might be enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM