在Spring Boot中对JPA存储库的Save方法进行单元测试

问题描述

您能告诉我如何使用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);
    }
}

解决方法

几天前,我也遇到过同样的情况,

@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()));
,

首先,您要支持构造函数注入而不是字段注入。没有studentRepository的依赖,studentService应该不起作用。更改后,您可以使用例如Mockito进行单元测试。采取的步骤:

  1. 对于junit 5,使用ExtendsWith(MockitoExtension.class)注释类,对于JUnit 4,使用@RunWith(MockitoJunit4ClassRunner.class)注释类。
  2. 通过用@Mock注释该类型的变量来创建StudentRepository Mock。
  3. 通过用@InjectMocks注释服务的变量来将模拟注入服务中
  4. 然后您要定义模拟行为。您可以在构造时使用嘲笑来做到这一点。就像when(studentRepository.myMethod()).thenReturn(MyCustomObject())
  5. 调用服务方法
  6. 声明有关您服务的某些行为。例如,您可以使用Mockito的verify构造来测试studentRepository.save()被调用一次。附带说明一下,保存不应返回void,而实际上应返回实体本身。
,

您的方法有两件事,难以测试。

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

您可以将两者分开,将Student的创建内容提取到一个单独的方法中(可能在您的服务中,但也可以在Student或StudentModel类中)。您可以根据需要单独测试该方法。这样避免了需要通过ArgumentCaptor对此进行测试。

将其放置在适当的位置,您可以按照Daniel’sBorsuk’s的答案来验证您的服务是否实际上调用了存储库的save方法。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...