当我尝试模拟一个方法并且该方法具有具有新类的局部变量时,获取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());
}
}