I'm starting to learn both Java and Spring boot now, and I'm having some problems with dependency injection in integration tests. I have a class under src/main/java/com/rfd/domain/services called TransactionService, which is marked as @Service and which has another dependencies, one of them a repository created by Spring boot. When I launch the application, it is launched correctly so I assume the dependencies are being resolved correctly. This is the summarized class:
package com.rfd.domain.services;
import allNeededImports
@Service
public class TransactionsService {
@Autowired
private KambiTransactionRepository kambiTransactionRepository;
@Autowired
private TransactionFactory transactionFactory;
public List<Transaction> retrieveTransactions(String couponExternalId) throws InvalidTransactionException {
// someCode
}
}
and now, I have a TransactionsServiceTests class under /src/test/java/com/rfd/integrationtests/domain/services:
package com.rfd.integrationtests.domain.services;
import allNeededImports
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Main.class)
@DataMongoTest
@TestPropertySource(locations = "classpath:application-integrationtest.properties")
public class TransactionsServiceTests {
@Autowired
private TransactionsService transactionsService;
@Test
public void retrieveTransactions_happyPathMultipleTransactions_transactionsRetrieved() throws InvalidTransactionException {
// test code
}
When I try to launch the tests, I receive the following error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.rfd.domain.services.TransactionsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
I have tried to create my own @TestConfiguration class, in which I create a method marked with @Bean and returning a new instance of TransactionService, and it works. However, the error now is for the KambiTransactionRepository dependency, and I don't have an implementation of it because it is given by spring boot:
package com.rfd.infrastructure.repositories;
import com.rfd.infrastructure.models.KambiTransaction;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface KambiTransactionRepository extends MongoRepository<KambiTransaction, String> {
List<KambiTransaction> findByCouponRef(String couponRef);
}
QUESTION How can I execute the integration test using the dependency resolution of the main code?
As @M.Deinum remarked in comments,
@SpringBootTest
and@DataMongoTest
are mutually exclusive, so removing@DataMongoTest
solved the problem.However, if you still want to use the
@DataMongoTest
annotation, you can use this sentence:That way, all classes tagget with annotation
@Service
will be loadad and autowired. Same with@Component
,@Repository
or@Controller