简体   繁体   English

如何使用服务和存储库为spring数据设置单元测试?

[英]How to set up a unit test for spring data with service and repository?

I have checked many SO comments and the docs for spring data and unit testing but I cant get this to work and I dont know why its not working. 我已经检查了很多SO注释和有关弹簧数据和单元测试的文档,但是我无法使其正常工作,而且我不知道为什么它不起作用。

I have a junit test class that looks like this: 我有一个junit测试类,看起来像这样:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class DealServiceTest {

    @Configuration
    static class ContextConfiguration {

        // this bean will be injected into the OrderServiceTest class
        @Bean
        public DealService orderService() {
            DealService dealService = new DealService();
            // set properties, etc.
            return dealService;
        }

        @Bean
        public EmployeeService employeeService(){
            EmployeeService employeeService = new EmployeeService();
            return employeeService;
        }

    }

    @Autowired
    DealService dealService;

    @Autowired
    EmployeeService employeeService;

    @Test
    public void createDeal() throws ServiceException {
        Employee employee = new Employee("Daniel", "tuttle", "danielptm@me.com", "dannyboy", "secret password", 23.234, 23.23);
        Deal d = dealService.createDeal("ADSF/ADSF/cat.jpg", "A title goes here", "A deal description", 23.22, "Name of business", 23.23,23.23, employee, "USA" );
        Assert.assertNotNull(d);

    }

} }

And then I have my service class that looks like this 然后我的服务类如下所示

@Service
public class DealService {

    @Autowired
    private DealRepository dealRepository;

    public Deal createDeal(String image, String title, String description, double distance, String location, double targetLat, double targetLong, Employee employee, String country) throws ServiceException {
        Deal deal = new Deal(image, title, description, distance, location, targetLat, targetLong, employee, country);
        try {
            return dealRepository.save(deal);
        }catch(Exception e){
            throw new ServiceException("Could not create a deal: "+deal.toString(), e);
        }
    }

    public Deal updateDeal(Deal d) throws ServiceException {
        try{
            return dealRepository.save(d);
        }catch(Exception e){
            throw new ServiceException("Could not update deal at this time: "+d.toString(),e);
        }
    }

    public List<Deal> getAllDealsForEmployeeId(Employee employee) throws ServiceException {
        try{
            return dealRepository.getAllDealsBy_employeeId(employee.getId());
        }catch(Exception e){
            throw new ServiceException("Could not get deals for employee: "+employee.getId(), e);
        }
    }

}

And then my repository: 然后我的存储库:

*/ * /

public interface DealRepository extends CrudRepository<Deal, Long>{

    public List<Deal> getDealsBy_country(String country);

    public List<Deal> getAllDealsBy_employeeId(Long id);

}

My config file looks like this: 我的配置文件如下所示:

@Configuration
@EnableJpaRepositories("com.globati.repository")
@EnableTransactionManagement
public class InfrastructureConfig {

    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setDriverClassName("com.mysql.jdbc.Driver");
        config.setJdbcUrl("jdbc:mysql://localhost:3306/DatabaseProject");
        config.setUsername("awesome");
        config.setPassword("database");
        return new HikariDataSource(config);
    }

//  @Bean
//  public DataSource derbyDataSource(){
//      HikariConfig config = new HikariConfig();
//      config.setDriverClassName("jdbc:derby:memory:dataSource");
//      config.setJdbcUrl("jdbc:derby://localhost:1527/myDB;create=true");
//      config.setUsername("awesome");
//      config.setPassword("database");
//
//      return new HikariDataSource(config);
//
//  }

    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory factory) {
        return new JpaTransactionManager(factory);
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {

        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setDatabase(Database.MYSQL);
        adapter.setGenerateDdl(true);

        return adapter;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(dataSource()); //Get data source config here!
        factory.setJpaVendorAdapter(jpaVendorAdapter());
        factory.setPackagesToScan("com.globati.model");

        return factory;
    }
}

But I get this error. 但是我得到这个错误。

java.lang.IllegalStateException: Failed to load ApplicationContext ... java.lang.IllegalStateException:无法加载ApplicationContext ...

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.globati.repository.DealRepository]: expected at least 1 bean which qualifies as autowire candidate. 由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:未找到依赖项的合格bean [com.globati.repository.DealRepository]:期望至少有1个有资格作为自动装配候选的bean。 Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 依赖项注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}

Any suggestions for how I can successfully do unit testing with spring data, junit and with my service and repositories would be greatly appreciated. 对于如何使用spring数据,junit以及我的服务和存储库成功进行单元测试的任何建议,将不胜感激。 Thanks! 谢谢!

For a repository bean to be injected, 对于要注入的存储库Bean,

  • You need to enable Repositories, using one of the spring-data annotations. 您需要使用spring-data批注之一启用存储库。 So add @Enable*Repositories to your configuration class 因此,将@Enable*Repositories添加到您的配置类中

  • You also need dB factories and other related beans configured. 您还需要配置dB工厂和其他相关的bean。 I am using Mongo and I have mongoDbFactory bean configured 我正在使用Mongo并且配置了mongoDbFactory bean

  • And for the most part your test configuration should look like your main configuration except for unnecessary bean replaced by mock implementations 而且在大多数情况下,您的测试配置应该看起来像您的主配置,只是不必要的bean被模拟实现所替代

UPDATE Here is my code (sorry mine is in mongo, I think you can relate) 更新这是我的代码(对不起,我在mongo中,我想你可以联系一下)

@Configuration
@WebAppConfiguration
@ComponentScan(basePackages = "com.amanu.csa",
        excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = WebConfig.class))
@EnableMongoRepositories(repositoryImplementationPostfix = "CustomImpl")
class TestConfig {

    @Bean
    Mongo mongo() throws Exception {
        return new MongoClient("localhost")
    }

    @Bean
    MongoDbFactory mongoDbFactory() throws Exception {
        return new SimpleMongoDbFactory(mongo(), "csa_test")
    }

    @Bean
    MongoTemplate mongoTemplate() throws Exception {
        MongoTemplate template = new MongoTemplate(mongoDbFactory())
        template.setWriteResultChecking(WriteResultChecking.EXCEPTION)
        return template
    }
}

That is my test config file... As you can see it explicitly excludes my main configuration file. 那是我的测试配置文件...如您所见,它明确排除了我的主配置文件。

@ContextConfiguration(classes = TestConfig)
@RunWith(SpringRunner.class)
class OrganizationServiceTest {

    @Autowired
    OrganizationService organizationService

     @Test
    void testRegister() {
        def org = new Organization()
        //...
        organizationService.register(org)
        // ...
    }

And that is my test class. 那是我的测试课。 It refers to the test config, and I recommend using named config classes. 它指的是测试配置,我建议使用命名的配置类。 You can put common options onto a super class and extend those and use them for your tests. 您可以将通用选项放在一个超类上,并将其扩展并用于测试。

I hope this helps 我希望这有帮助

You can try to add 您可以尝试添加

@ActiveProfiles("your spring profile") 

In addition I would suggest to use an embedded test db like flapdoodle ( https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo ) 另外,我建议使用嵌入式测试数据库,例如flappoodle( https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo

You could either : 您可以:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对使用存储库的服务层进行春季单元测试? - How to do a Spring Unit Test of a Service layer that use Repository? 带有控制器的单元测试Spring Boot-&gt;服务-&gt;存储库 - Unit Test Spring Boot with Controller -> Service -> Repository Spring Unit测试JPA存储库 - Spring Unit test JPA repository 如何在单元测试中设置 Spring 注入的值? - How to set a value injected by Spring in a unit test? Spring Web Flow - 如何使用conversationScope中已有的值设置单元测试? - Spring Web Flow - How can I set up unit test with values already in conversationScope? 单元测试 Spring 服务与映射器和存储库的连接 - Unit testing Spring Service with the connections to Mapper and Repository 如何为 GET Rest 服务创建单元测试(春季) - How to create a unit test for a GET Rest service (Spring) Spring Boot:如何在单元测试中使用 liquibase 设置测试数据 - Spring Boot: How to setup test data with liquibase in unit test 如何使用 Spring Boot + Spring Data JPA 对悲观锁定进行单元测试 - How to unit test pessimistic locking with Spring Boot + Spring Data JPA Spring - 使用 Mock 进行单元测试 - 如何在服务单元测试中模拟自定义收集器 - Spring - Unit Test with Mock - How to mock a Custom Collector in a Service unit test
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM