I am trying to test my springboot controller /save endpoint. I want to test that if you send a json request with a null agency name you should get back a 400 status and the response “Agency Name cannot be null.”
This works during local testing with postman, but I haven’t been able to get it working in junit.
Heres my code
jUnit:
@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());
}
It gives me this response
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
While debugging, I did notice something interesting in the controller.
My controller checks using a custom method called postFieldValidation
Controller
@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);
}
Post field Validation inside service
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;
}
I noticed that updatedValues has the proper definition inside of the controller, but inside of the service it is null and skips the validation.