执行单元测试时spring boot应用程序是不是需要连接到数据库

Posted

技术标签:

【中文标题】执行单元测试时spring boot应用程序是不是需要连接到数据库【英文标题】:Is it required for spring boot application to be connected to database when performing unit test执行单元测试时spring boot应用程序是否需要连接到数据库 【发布时间】:2021-01-16 01:49:42 【问题描述】:

我正在为服务层编写单元测试用例。这是我的服务类:

@Service
@RequiredArgsConstructor
public class EmpService 

    private final EmpRepository empRepository;

    public EmployeeDto findById(UUID id) 
        return empRepository.findById(id).map(this::mapToEmployeeDto);
    

测试类:

@SpringBootTest
class EmpServiceTest 
    @Autowired
    EmpService empService;
    
    @MockBean
    EmpRepository empRepository;
    
    @Test
    void get_employee_by_id_success_case() throws IOException 

        UUID empId = UUID.fromString("2ec828f5-35d5-4984-b783-fe0b3bb8fbef"); 
        EmployeeDto expectedEmp = new EmployeeDto(empId, "James");
        EmployeeEntity stubbedEmployee = new EmployeeEntity(empId, "James");
        when(empRepository.findById(any(UUID.class)))
            .thenReturn(Optional.of(stubbedEmployee));
        EmployeeDto actualEmp = empService.findById(empId);
        assertEquals(expectedEmp, actualEmp);
    

我正在为我的数据库 (postgres) 使用 docker 图像。当容器为db启动时,上面的测试用例就运行成功了。

但是当我停止整个 docker 应用程序时,会出现以下错误:

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'empRepository' defined in repo.EmpRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution

单元测试用例不应该独立于数据库,特别是当我们模拟 repo bean 时?

想象一个人在他们的机器上重新签出这段代码,并在没有设置数据库的情况下首先构建项目。在这种情况下,单元测试应该运行并且不应该依赖于数据库。

请注意我使用的是 JUnit 5 (Jupiter),spring-boot-starter-test kit。

【问题讨论】:

@Kayaman 用于代码覆盖。目前应用还处于非常初级的阶段。随着时间的推移,更多的逻辑将被添加到其中。您可以认为测试是检查是否在愉快的情况下返回了正确的 dto。 您已自动连接 EmpService,它必须连接到存储库。尝试模拟 EmpService。 @MS- 如果我这样做,那么我将如何调用我想要测试的方法 ***.com/questions/51161200/… 看看这个。 @SpringBootTest 加载应用程序上下文,这就是 bean 创建失败的原因。 【参考方案1】:

在我看来,你写的更多的是集成测试,而不是单元一。

除了语义,还有一个非常好的框架testcontainers,它将在docker容器中运行数据库,只是为了测试阶段。

这篇文章展示了如何设置此类数据库测试:https://programmerfriend.com/spring-boot-integration-testing-done-right/

【讨论】:

以上是关于执行单元测试时spring boot应用程序是不是需要连接到数据库的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 不运行单元测试

如何为我的 Spring Boot 控制器执行单元测试?

Spring Boot - 我的单元测试被跳过

Spring Boot DataJpaTest 单元测试恢复到 H2 而不是 mySql

Spring boot web 单元测试程序

Spring Boot maven 多模块项目——单元测试(应用上下文)