【问题标题】:Unit testing a Spring Boot service class with(out) repository in JUnit在 JUnit 中对带有(出)存储库的 Spring Boot 服务类进行单元测试
【发布时间】:2013-10-29 09:31:50
【问题描述】:

我正在开发一个基于 Spring Boot 的 Web 服务,其结构如下:

控制器 (REST) --> 服务 --> 存储库(如某些教程中所建议的那样)。

我的数据库连接(JPA/Hibernate/MySQL)在 @Configuration 类中定义。 (见下文)

现在我想为我的 Service 类中的方法编写简单的测试,但我真的不明白如何将 ApplicationContext 加载到我的测试类中以及如何模拟 JPA / Repositories。

这是我走了多远:

我的服务类

@Component
public class SessionService {
    @Autowired
    private SessionRepository sessionRepository;
    public void MethodIWantToTest(int i){
    };
    [...]
}

我的测试课:

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

    @Configuration
    static class ContextConfiguration {
        @Bean
        public SessionService sessionService() {
            return new SessionService();
        }
    }

    @Autowired
    SessionService sessionService;
    @Test
    public void testMethod(){
    [...]
  }
}

但我得到以下异常:

引起:org.springframework.beans.factory.BeanCreationException: 创建名为“sessionService”的 bean 时出错:注入自动装配 依赖失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:不能 自动装配字段:私有 com.myApp.SessionRepository com.myApp.SessionService.sessionRepository;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 为 [com.myApp.SessionRepository] ​​找到了符合条件的 bean 依赖项:预计至少有 1 个符合自动装配条件的 bean 这种依赖的候选人。依赖注解: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

为了完整性:这是我的 jpa 的 @Configuration:

@Configuration
@EnableJpaRepositories(basePackages={"com.myApp.repositories"})
@EnableTransactionManagement
public class JpaConfig {


    @Bean
    public ComboPooledDataSource dataSource() throws PropertyVetoException, IOException {
        ...
    }

   @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        ...
    }


    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        ...
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
   ...
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
  ... 
   }
}

【问题讨论】:

    标签: java spring junit spring-boot


    【解决方案1】:

    使用@SpringBootTest 和@RunWith(SpringRunner.class) 加载上下文

    @RunWith(SpringRunner.class)
    @SpringBootTest
    class Demo{
        @Test
        void contextLoad(){}
    }
    

    【讨论】:

      【解决方案2】:

      在您的测试中,Spring 将仅使用内部 ContextConfiguration 类的配置。此类描述您的上下文。在这种情况下,您只创建了服务 bean 而没有创建存储库。因此,将创建的唯一 bean 是 SessionService。您应该在内部 ContextConfiguration 中添加 SessionRepository 的描述。您的 JpaConfig 类不会在测试类中使用(您没有指定这个),仅在应用程序中使用。

      【讨论】:

      • 好的,我想我明白了。但是存储库是接口,我怎样才能像 SessionService 一样实例化它们?!
      • 您说应用程序具有结构控制器 (REST) --> 服务 --> 存储库。这意味着存储库是访问数据库 (DAO) 的类。因此,如果 SessionRepository 是接口,您应该在您的应用程序中实现它。在其他情况下,当你开始你的项目时,Spring 会得到同样的异常,因为它不会找到任何实现指定接口的类。
      • Boot 使用 Spring-Data-JPA (projects.spring.io/spring-data-jpa),你只定义一个接口,spring 以某种方式自动提供实现。在我的服务中,我只是 @Autowire 他们,但不知道这应该如何与测试一起工作。
      • 好的,我明白你想要什么。首先尝试在 JpaConfig 应用程序上下文上启动测试。您应该尝试在文本类 @ContextConfiguration(classes = {JpaConfig.class}) 上使用此注释
      • mh 知道了,但没有改变异常。
      猜你喜欢
      • 2018-11-09
      • 2019-03-20
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 2019-01-23
      • 2015-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多