Powermock+JUnit - 带有新类的 NullPointerException



当我尝试模拟一个方法并且该方法具有具有新类的局部变量时,获取NullPointerException。 尝试了不同的方式,但没有运气。请参阅评论,我已经提到了我尝试过的内容以及我在哪里得到例外。

提前感谢!

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(StudentController.class)
    public class StudentControllerTest {
        @Mock
        HttpServletRequest request;
        @Mock
        StudentService studentService;
        @InjectMocks
        StudentController studentController;
        @Test
        public void create() {
            Student student =mock(Student.class);
            **// Also tried Student student = new Student();**
            student.setName("Name");
            student.setAddress("New York");
            when(studentService.create(student)).thenReturn(student);
            // if I try below code I am getting compile error - Type mismatch: cannot convert from Matcher<Student> to Student
 //when(studentService.create(any(Student.class))).thenReturn(student);
            Student createdStudent= studentController("Name", "New York", 1);
            assertTrue(0 < createdStudent.getStudentId())
        }
    }

学生控制器.java

@PostMapping("/api/student/create")
public Student create(HttpServletRequest request, @RequestParam("name") String name, @RequestParam("address") String address, @RequestParam("grade") String grade) {
    Student student = new Student();
    try {
        student.setName(name);
        student.setAddress(address);
        student.setGrade(Integer.decode(grade));
        student = studentService.create(student);
        **// Throwing NullPointer in this line. I did dubug and can see student returned is null**
        message = "Successfully Created Student[" + student.getId() + "] " + name;  
    } catch (Exception e) {
        message = "Exception while create the student: " + name;
        log.error(message + "n" + StackTraceUtil.getStackTrace(e));
        student.setErrorMessage(message);
    }
    return student;
}

溶液:

我正在使用org.hamcrest.CoreMatchers.any这给出了编译错误Type mismatch: cannot convert from Matcher<Student> to Student

现在我把它改成了org.mockito.ArgumentMatcher.any您可以任选以下两个之一。两者都会起作用。

关键是导入org.mockito.ArgumentMatcher.any

Student student =mock(Student.class);
student.setName("Name");
student.setAddress("New York");

Student student = new Student();
student.setName("Name");
student.setAddress("New York");

基于所测试的方法,与 new Student() 的紧密耦合以及测试中的匹配器设置与在被测试方法中创建的匹配器设置不匹配的事实,则studentService.create将返回 null

实际上不需要Student模拟,因为正在测试的方法已经在创建一个模拟。

使用更灵活的参数匹配器,如 any(Student.class) ,在设置中捕获传递的参数并设置所需的 id,以便被测方法可以完成。

例如

@RunWith(PowerMockRunner.class)
@PrepareForTest(StudentController.class)
public class StudentControllerTest {
    @Mock
    HttpServletRequest request;
    @Mock
    StudentService studentService;
    @InjectMocks
    StudentController studentController;
    @Test
    public void create() {
        //Arrange
        int expectedId = 1;
        when(studentService.create(any(Student.class)))
            .thenAnswer(i -> {
                Student student = (Student)i.getArguments()[0];
                //manipulate the student as needed.
                //Like setting an id
                //...student.setId(expectedId)
                return student;
            });
        //Act
        Student createdStudent = studentController.create(request, "Name", "New York", 1);
        //Assert
        assertTrue(createdStudent != null);
        assertTrue(expectedId == createdStudent.getStudentId());
    }
}

相关内容

  • 没有找到相关文章