我正在尝试测试我的 springboot 控制器/保存端点。我想测试一下,如果您发送带有空机构名称的 json 请求,您应该返回 400 状态和响应“机构名称不能为空。”
这在使用邮递员进行本地测试期间有效,但我无法使其在 junit 中工作。
这是我的代码
j单位:
@SpringBootTest
@AutoConfigureMockMvc
@WithMockUser(username = "test", password = "test", authorities = { "ANY " })
public class AgencyControllerIT {
@Autowired
private MockMvc mvc;
@Mock
private AgencyRepository mRepository;
@MockBean
private AgencyService mService;
@Test
public void testControllerSaveWithoutAgencyName() throws Exception {
// Create JSON
String body = "[{" +
"\"agency\": null," +
"\"type\": \"Type\"," +
"\"defaultText\": \"DefaultText\""
"}]";
//Perform request to endpoint and assert bad request
this.mvc.perform(MockMvcRequestBuilders.post("/myApplication/save")
.contentType(MediaType.APPLICATION_JSON)
.content(body))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(content().string("Agency Name cannot be null"))
.andReturn();
//Verify service is not called
verify(mService, times(0)).merge(any());
}
它给了我这样的回应
MockHttpServletRequest:
HTTP Method = POST
Request URI = /myApplication/save
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8"]
Body = [{"agency:" null, "type": "Type","defaultText": "DefaultText"}]
Session Attrs = {}
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Content-Type:"application/json", X-Content-Type-Options:"nosniff", X-XSS-Protection:"0", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = application/json
Body = [ ]
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status expected:<400> but was:<200>
Expected :400
Actual :200
在调试时,我确实注意到控制器中有一些有趣的东西。
我的控制器使用名为 postFieldValidation 的自定义方法进行检查
控制器
@Transactional
@PostMapping(value = {"/save"}, produces = {"application/json"})
public ResponseEntity<List<Agency>> save(@RequestBody List<Agency> updatedValues){
String message = agencyService.postFieldValidation(updatedValues);
if(message != null){
return new ResponseEntity(message, HttpStatus.BAD_REQUEST);
}
List<Agency> result = agencyService.merge(updatedValues);
return new ResponseEntity<>(result, HttpStatus.OK);
}
在服务内进行字段验证
public String postFieldValidation(List<Agency> updatedValues) {
String message = null;
for (Agency updatedValue : updatedValues) {
if (updatedValue.getAgency() == null)
message = "Agency name cannot be null";
else if (updatedValue.getDefaultText() == null)
message = "Default Text cannot be null";
}
return message;
}
我注意到updatedValues在控制器内部有正确的定义,但在服务内部它是空的并跳过验证。
由于
AgencyService
作为 @MockBean
注入,因此 postFieldValidation
方法返回 null
,因为没有 when()
子句指定该方法必须作为模拟返回什么。
您必须在测试中注入“真实”
AgencyService
bean,或者,如果您需要其他方法的模拟,请定义部分模拟(如使用 Mockito 模拟某些方法而不是其他方法中所述)。