在模拟控制器类时,我无法在单元测试中覆盖catch块
这是代码-控制器类别-
public ResponseEntity<ResponseSentence> getText(@RequestBody Text text) throws IOException {
try {
return new ResponseEntity<>(serviceImpl.getText(text), HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
这是我的测试班
@Autowired
private MockMvc mockMvc;
@MockBean
private Service service;
@MockBean
private ServiceImpl serviceImp;
@Autowired
private ObjectMapper objectMapper;
@Test
void getText() throws Exception {
Text text = new Text();
text.setText("");
//given(service.getText(text)).willThrow(new IOException("boom"));
when(serviceImp.getText(text)).thenThrow(new IOException());
ResultActions response = mockMvc.perform(post("/opennlp/v1/sentence")
.contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(text)));
response.andDo(print()).
andExpect(status().isBadRequest());
Mockito.verify(serviceImp).getText(any());
}
而代码覆盖catch块不被覆盖。
问题的原因是测试方法中使用的Text
实例和运行测试时实际控制器代码中存在的Test
实例是两个独立的实例,并且Text
类没有定义equals
方法。在测试方法中,您使用构造函数(new
(创建一个对象,而在控制器方法中,传递由JacksonObjectMapper
创建的对象的一个单独实例。由于没有定义equals
方法,当Mockito比较不匹配的对象时,不会执行模拟行为。
您可以在Text
类中定义equals
方法(记住equals和hashCode方法契约(,也可以在使用Mockito定义行为时使用参数匹配器,这取决于您想要测试的内容:
when(serviceImp.getText(any()))
.thenThrow(new IOException());
when(serviceImp.getText(argThat(value => value.getText().isEmpty())))
.thenThrow(new IOException());
String someValue = "custom value";
text.setText(someValue);
when(serviceImp.getText(argThat(value => someValue.equals(value.getText()))))
.thenThrow(new IOException());