首页 > 解决方案 > Mockito 3 需要但未调用

问题描述

我正在尝试学习 Mockito 3,我在谷歌搜索中查看了几乎所有结果,但找不到有效的解决方案。我processStudent在一个测试用例中调用,它基于输入在内部调用另一个方法saveStudentsaveNullStudent.

 public String processStudent(String student) {
    System.out.println("StudentService.processStudent: it will process Student = " + student);
    String StudentRes;
    if (Objects.isNull(student)) {
        StudentRes = saveNullStudent(student);
        return StudentRes;
    } else {
        StudentRes = saveStudent(student);
        return StudentRes;
    }
}

public String saveNullStudent(String student) {
    System.out.println("StudentService.saveNullStudent: it will process then save Student = " + student);
    return student;
}

public String saveStudent(String student) {
    System.out.println("StudentService.saveStudent: it will process then save Student = " + student);
    return student;
}

我需要测试这两种情况,所以我的测试用例是

 @Test
void saveStudentWithMockTest() {
    StudentService StudentService = mock(StudentService.class);
    StudentService.processStudent("studentA");
    verify(StudentService, times(1)).saveStudent("studentA");
}

@Test
void saveStudentWithNullMockTest() {
    StudentService StudentService = mock(StudentService.class);
    StudentService.processStudent(null);
    verify(StudentService, times(1)).saveNullStudent(null);
}

但我得到

Wanted but not invoked:
studentService.saveNullStudent(null);
-> at StudentServiceTest.saveStudentWithNullMockTest(StudentServiceTest.java:21)

However, there was exactly 1 interaction with this mock:
studentService.processStudent(null);
-> at StudentServiceTest.saveStudentWithNullMockTest(StudentServiceTest.java:20)

摇篮文件

dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.6.2')
    testCompile 'org.mockito:mockito-junit-jupiter:3.4.4'
}

我不明白,这不是mockito的用途吗?

这个测试用例的重点不是单元测试,而是测试processStudent方法的行为,如果值为空,则根据输入数据调用方法saveNullStudent,否则saveStudent调用方法。

我做错了什么?

标签: javajunitmockito

解决方案


您应该只模拟要测试的类的依赖项。我的意思是,如果StudentService该类具有任何全局变量,例如其他服务或存储库类,那么这些就是您应该模拟的类。StudentService类本身应该是真实的。在您的情况下,更好的测试是检查processStudent两个测试用例的方法输出。例如:

import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class StudentServiceTest {

    private final StudentService studentService = new StudentService();

    @Test
    public void saveStudentWithMockTest() {
        String result = studentService.processStudent("studentA");

        assertThat(result).isEqualToIgnoringCase("studentA");
    }

    @Test
    public void saveStudentWithNullMockTest() {
        String result = studentService.processStudent(null);

        assertThat(result).isNull();
    }

}

推荐阅读