我正在尝试为我在 Spring 中为控制器实现的服务编写测试用例。我有以下服务和测试课程。
学生课程请求服务:
import java.util.List;
import org.springframework.stereotype.Service;
import model.CourseRequest;
import repository.ICourseRequestRepository;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class StudentCourseRequestService implements IStudentCourseRequestService {
private final ICourseRequestRepository courseRequestRepository;
@Override
public boolean requestCourse(CourseRequest courseRequest) {
return courseRequestRepository.saveRequest(courseRequest);
}
@Override
public List<CourseRequest> getAllCourseRequests() {
return courseRequestRepository.getAllCourseRequests();
}
@Override
public List<CourseRequest> getAllCourseRequestsOfStudent(Long studentId) {
return courseRequestRepository.getCourseRequestsByStudentId(studentId);
}
}
测试班:
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.springframework.boot.test.mock.mockito.MockBean;
import static org.assertj.core.api.Assertions.assertThat;
import model.CourseRequest;
import repository.ICourseRequestRepository;
public class StudentCourseRequestServiceTests {
@MockBean
private ICourseRequestRepository courseRequestRepository;
@InjectMocks
private StudentCourseRequestService studentCourseRequestService;
@Test
public void requestValidCourse() throws Exception {
final CourseRequest courseRequest = new CourseRequest(
"data0",
"data1",
"data2",
"data3",
"data4",
"data5"
);
Mockito.when(courseRequestRepository.saveRequest(courseRequest)).thenReturn(true);
boolean result = studentCourseRequestService.requestCourse(courseRequest);
assertThat(result).isTrue();
}
}
当我运行
requestValidCourse()
测试用例时,出现以下错误:
java.lang.NullPointerException: Cannot invoke "repository.ICourseRequestRepository.saveRequest(model.CourseRequest)" because "this.courseRequestRepository" is null
at service.StudentCourseRequestServiceTests.requestValidCourse(StudentCourseRequestServiceTests.java:29)
at java.base/java.util.ArrayList.forEach(Unknown Source)
at java.base/java.util.ArrayList.forEach(Unknown Source)
如何解决这个问题?
按照 @Lesiak 的建议,我将
@ExtendWith(MockitoExtension.class)
注释添加到类的顶部,并将 courseRequestRepository
更改为具有 @Mock
注释,而不是之前的 @MockBean
注释。这些更改后问题得到解决。
之前,我在试验期间使用了 @Lesiak 推荐的配置来解决该问题,但我还在类的顶部添加了注释
@ExtendWith(SpringExtension.class)
。使用此配置,我遇到了同样的错误。删除 @ExtendWith(SpringExtension.class)
注释解决了这里的问题。
新测试班:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.assertj.core.api.Assertions.assertThat;
import model.CourseRequest;
import repository.ICourseRequestRepository;
@ExtendWith(MockitoExtension.class)
public class StudentCourseRequestServiceTests {
@Mock
private ICourseRequestRepository courseRequestRepository;
@InjectMocks
private StudentCourseRequestService studentCourseRequestService;
@Test
public void requestValidCourse() throws Exception {
final CourseRequest courseRequest = new CourseRequest(
"data0",
"data1",
"data2",
"data3",
"data4",
"data5"
);
Mockito.when(courseRequestRepository.saveRequest(courseRequest)).thenReturn(true);
boolean result = studentCourseRequestService.requestCourse(courseRequest);
assertThat(result).isTrue();
}
}
请注意以下几点:
你在使用
@org.mockito.InjectMocks
吗?
JUnit版本: 2.1)如果是JUnit 4,则配置测试类如下:
@org.junit.Before
public void setUp() {
org.mockito.MockitoAnnotations.openMocks(this);
}
2.2) 如果是 JUnit 5:
@org.junit.BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
就我而言,我在课堂上没有使用
@ExtendWith(MockitoExtension.class)
。