Springboot:如何使用真正的依赖项执行集成测试?

时间:2017-08-24 11:51:47

标签: java spring-boot dependency-injection integration-testing

我现在开始学习Java和Spring启动,并且我在集成测试中遇到了一些依赖注入问题。我在 src / main / java / com / rfd / domain / services 下有一个名为TransactionService的类,它被标记为@Service并且有另一个依赖项,其中一个Spring启动创建的存储库。当我启动应用程序时,它正确启动,因此我假设依赖关系正在正确解析。这是总结的类:

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
    }
}

现在,我在 / src / test / java / com / rfd / integrationtests / domain / services 下有一个TransactionsServiceTests类:

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
    }

当我尝试启动测试时,收到以下错误:

  

引起:   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   属于&#39; com.rfd.domain.services.TransactionsService&#39;的限定bean   可用:预计至少有1个符合autowire资格的bean   候选人。依赖注释:   {@ org.springframework.beans.factory.annotation.Autowired(所需=真)}

我试图创建自己的@TestConfiguration类,在其中我创建一个标有@Bean的方法并返回一个新的TransactionService实例,它可以工作。但是,现在的错误是KambiTransactionRepository依赖项,我没有实现它,因为它是由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);
}

问题 如何使用主代码的依赖性解析执行集成测试?

2 个答案:

答案 0 :(得分:3)

正如@ M.Deinum在评论中所说,'Comment ça va ?'.gsub(/\b\p{L}{1,2}\b/, '').squeeze(' ').strip => "Coment ?" @SpringBootTest是互斥的,因此删除@DataMongoTest解决了问题。

但是,如果您仍想使用@DataMongoTest注释,可以使用以下句子:

@DataMongoTest

这样,带注释@DataMongoTest(includeFilters = @ComponentScan.Filter(Service.class)) 的所有类标记都将被加载并自动装配。与@Service@Component@Repository

相同

答案 1 :(得分:1)

我需要为我的存储服务添加测试,我需要自动装配 MongoRepository。这个问题的答案并没有解决我的问题。但是我找到了一个解决方案,如果其他人需要,我会在这里分享。我是这样解决的:

存储库:

@Repository
public interface MyRepository extends MongoRepository<MyEntity, String> {
}

实体:

@Document(collection = "my_entity")
public class MyEntity {
    @Id
    private String id;
}

服务:

@Service
public class StorageServiceImpl implements StorageService {
    private final MyRepository repository;

    public StorageServiceImpl(MyRepository repository) {
        this.repository = repository;
    }
...
}

测试:

@Import(ObjectMapperConfiguration.class)
@DataMongoTest
class StorageServiceImplTest {

    @Autowired
    private MyRepository repository;

    private StorageService storageService;

    @BeforeEach
    void setup() {
        storageService = new StorageServiceImpl(repository);
        var entity = new MyEntity();
        repository.save(entity);
    }

    @Test
    void create() {
        assertEquals(1, repository.count());
        var entity = storageService.create();
        assertEquals(2, repository.count());
    }
...
}

测试配置:

@TestConfiguration
public class ObjectMapperConfiguration {
    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
    }
}

测试应用

@SpringBootApplication
public class TestApplication {
}