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.