Spring Boot中JPA Repository的Save方法的单元测试

Posted

技术标签:

【中文标题】Spring Boot中JPA Repository的Save方法的单元测试【英文标题】:Unit test for Save method of JPA Repository in Spring Boot 【发布时间】:2020-12-11 01:06:48 【问题描述】:

您能告诉我应该如何使用 Mockito 和 JUnit 为这段代码编写单元测试吗? StudentRepository 是一个扩展 JPA Repository 的接口。

public class StudentService 
    @Autowired
    StudentRepository studentRepository;
    
    public void saveStudentDetails(StudentModel student) 
        Student stud = new Student();
        stud.setStudentId(student.getStudentId());
        stud.setStudentName(student.getStudentName());
        studentRepository.save(stud);
    

【问题讨论】:

【参考方案1】:

首先,您希望构造函数注入优于字段注入。如果没有 studentRepository 的依赖,studentService 将无法工作。更改后,您可以使用 Mockito 进行单元测试。采取的步骤:

    在 junit 5 的情况下使用 ExtendsWith(MockitoExtension.class) 或在 JUnit 4 的情况下使用 @RunWith(MockitoJunit4ClassRunner.class) 注释类。 通过使用@Mock 注释该类型的变量来创建StudentRepository Mock 通过使用@InjectMocks 注释服务的变量将模拟注入服务 那么您想定义模拟行为。您可以在构造时使用模拟来执行此操作。类似于when(studentRepository.myMethod()).thenReturn(MyCustomObject()) 调用服务方法 断言有关您的服务的某些行为。例如,您可以使用 mockito 的 verify 构造来测试 studentRepository.save() 是否被调用一次。附带说明一下,保存不应返回 void,而应实际返回实体本身。

【讨论】:

【参考方案2】:

几天前我也遇到过同样的情况,我想到了这样的事情。

@InjectMocks
StudentService studentService;
@Mock
StudentRepository studentRepository;

public void saveStudentDetailsTest()
    //given
    StudentModel student = new StudentModel(Your parameters);
    //when
    studentService.saveStudentDetails(student);
    //then
    verify(studentRepository, times(1)).save(any());

您也可以使用 ArgumentCaptor 并检查您传递来保存的对象是否是您想要的,它可能看起来像这样

ArgumentCaptor<Student> captor = ArgumentCaptor.forClass(Student.class);
verify(studentRepository).save(captor.capture());
assertTrue(captor.getValue().getStudentName().equals(student.getStudentName()));

【讨论】:

【参考方案3】:

你的方法做了两件事,很难测试。

该方法首先从 StudentModel 创建一个 Student 对象,然后保存 Student 对象。

您可以将两者分开,将 Student 创建提取到单独的方法中(可以在您的服务中,但也可以在 Student 或 StudentModel 类中)。如果您愿意,您可以单独对该方法进行单元测试。这避免了通过 ArgumentCaptor 进行测试的需要。

有了这个,您可以按照Daniel’s 或Borsuk’s 的回答来验证您的服务是否确实调用了存储库的保存方法。

【讨论】:

以上是关于Spring Boot中JPA Repository的Save方法的单元测试的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot(17)——使用Spring Data JPA

Spring Boot:在Spring Boot中使用Mysql和JPA

spring boot jpa 配置了yml文件后怎么扫描包

Spring boot之 JPA/Hibernate/Spring Data

spring-boot与spring-data-JPA的简单集成使用

IDEA spring boot jpa简单案例