即使所有服务都已注释,也能获取此 NPE 这是代码,我想我也可以得到 EncryptDecryptService 的类似错误,尽管现在还没有得到它
错误
java.lang.NullPointerException: Cannot invoke "comservice.service.SearchService.searchPatient(com.service.requests.SearchPatientRequest)" because "this.patientSearchService" is null
at com.service.Controller.SearchControllerIntegrationTest.testSearchPatients(SearchControllerIntegrationTest.java:72)
控制器类
RestController
@Slf4j
public class SearchController {
@Autowired
SearchServiceImpl SearchService;
@Autowired
SearchService psService;
@Autowired
private EncryptDecryptService encryptDecryptService;
@GetMapping("/search")
public ResponseEntity<SearchResponse> searchPatients(SearchPatientRequest message) {
SearchResponse response = new SearchResponse();
try {
patientSearchService.setEncryptor(encryptDecryptService);
List<Patient> patients = psService.searchPatient(message);
response.setStatus(1);
if (patients.isEmpty()) {
SearchResponse.Results results = response.getResults();
results.setPatients(patients);
response.setResults(results);
} else {
SearchResponse.Results results = response.getResults();
results.setPatients(patients);
response.setResults(results);
}
log.info("PSS search request, Response count: {}", patients.size());
} catch (IllegalArgumentException e) {
response.setResults(null);
response.setStatus(0).setErrorMessage(e.getMessage());
} catch (Throwable e) {
log.error("PSS Error occurred: {}", e);
response.setResults(null);
response.setStatus(0).setErrorMessage("No Patient Found!!");
}
return new ResponseEntity(response, HttpStatus.OK);
}
}
测试用例
@ExtendWith(MockitoExtension.class)
@WebMvcTest(SearchController.class)
@AutoConfigureMockMvc
@ActiveProfiles("test")
public class SearchControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@MockBean
SearchServiceImpl patientSearchService;
@MockBean
private EncryptDecryptService encryptDecryptService;
@InjectMocks
private SearchController patientSearchController;
private ObjectMapper objectMapper;
@BeforeEach
public void setUp() {
MockitoAnnotations.initMocks(this);
objectMapper = new ObjectMapper();
}
@Test
public void testSearchPatients() throws Exception {
SearchPatientRequest request = new SearchPatientRequest();
request.setPatientType("New");
request.setPatientId("74478");
when(patientSearchService.searchPatient(any(SearchPatientRequest.class)))
.thenReturn(Collections.singletonList(new Patient()));
when(encryptDecryptService.encryptString(anyString())).thenReturn("encryptedValue");
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/search")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn();
String responseBody = result.getResponse().getContentAsString();
SearchResponse searchResponse = objectMapper.readValue(responseBody, SearchResponse.class);
assertNotNull(searchResponse.getResults());
assertFalse(searchResponse.getResults().getPatients().isEmpty());
}
}
pom 版本
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<!-- Mockito Core -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
<!-- Mockito JUnit Jupiter -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
无法找出遗漏或错误的内容
我希望这些测试用例通过 mvn clean test 命令运行
我相信您将一些不同的概念混合在一起,最终导致它不符合您的预期。让我将其分解为每个观察结果:
您将
MockitoExtension
与 WebMvcTest
和 AutoConfigureMockMvc
一起使用。 WebMvcTest
(取决于您的 Spring 版本)包括 AutoConfigureMockMvc
,因此您不需要包含它。此外,Spring 在内部为您做了很多事情,这使您不再需要直接使用 MockitoExtension
,所以我首先开始并删除该注释。
其次,在您的测试中,使用了
@InjectMocks
,但最终您只是直接调用该服务。看来您甚至没有在测试中使用 patientSearchController
,因此我将删除它,因为它只在 WebMvcTest
注释中的参考中需要。如果您稍后确实需要使用它,则如果您需要修改任何方法调用,则应使用 @Autowired
或 @SpyBean
对其进行注释。
第三,您当前的用例中不需要
@BeforeEach
设置方法,因为所有内容都应该通过 WebMvcTest
进行设置。另外 ObjectMapper
是由 Spring 提供的,所以除非你只想要一个全新的,否则你可以通过添加 @Autowired
注解来使用它。
第四,我没有看到
patientSearchService
连接在控制器代码中,因此您需要确保它可以通过 @Autowired
注释或通过将该字段作为最终字段的构造函数使用(如果您使用 Lombok,则 @RequiredArgsConstructor
很有帮助)。
清理完上述内容后,您将获得成功的运行或指导您成功运行的新消息。