如何使用spring框架在存储库上测试具有@Autowire的服务类?

时间:2016-12-23 23:29:01

标签: java spring spring-mvc

我整天坐在这里,我不知道为什么这不起作用。此外,此测试适用于spring引导项目,但出于某种原因,在此Spring框架项目中,此测试不起作用并且抛出的错误是

  

java.lang.IllegalStateException:无法加载ApplicationContext   引起:   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   发现依赖的限定bean   [com.globati.repository.DealRepository]:预计至少有1个bean   有资格成为autowire候选人。依赖注释:

我的测试类看起来像这样:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/spring/DealServiceTest-context.xml"})
public class DealServiceTest {

    @Autowired
    DealService dealService;

    @Autowired
    EmployeeService employeeService;

    @Test
    public void createDeal() throws ServiceException {
        Assert.assertEquals(1, 1);
//        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);

    }

DealService看起来像这样:

@Service
public class DealService {

    @Autowired
    private DealRepository dealRepository;

    DealService(){}

    public DealService(DealRepository dealRepository){
        this.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);
        }
    }

}

DealRepository看起来像这样

public interface DealRepository extends CrudRepository<Deal, Long>{

    public List<Deal> getDealsBy_country(String country);

    public List<Deal> getAllDealsBy_employeeId(Long id);

}

我有一个看起来像这样的配置文件

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

这是我项目的目录结构的外观 Directory structure of project

DealServiceTest-context.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

            <!-- this bean will be injected into the OrderServiceTest class -->
    <bean id="dealService" class="com.globati.service.DealService">
    </bean>

    <bean id="employeeService" class="com.globati.service.EmployeeService">
        <!-- set properties, etc. -->
    </bean>

    <!--<bean id="employeeRepository" class="com.globati.repository.EmployeeRepository">-->

    <!--</bean>-->

            <!-- other beans -->
</beans>

出于某种原因,这个@Autowire在DealService中的DealRepository上的行为与弹簧启动项目中的行为不同。关于如何解决此错误并对服务类进行单元测试的任何想法将不胜感激!

1 个答案:

答案 0 :(得分:1)

尝试为profile添加测试DataSource,如下所示,

@Bean
@Profile("test")
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);
}

然后使用@ActiveProfiles("test")注释您的测试类,如下所示,

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/spring/DealServiceTest-context.xml"})
@ActiveProfiles("test")
public class DealServiceTest {

这将确保您在测试用例中执行时获得DataSource