I am unit testing with MockMvc for the first time and I have not figured it out yet how to use it correctly.
I am trying to test a simple POST method.
My code (class code) works good, I tested it with postman, so clearly the problem is with the testing code.
Controller:
@Controller
@RequestMapping("/employees")
public class EmployeeController {
private final EmployeeService employeeService;
private final EmployeeModelAssembler assembler;
@Autowired
public EmployeeController(EmployeeService employeeService, EmployeeModelAssembler assembler){
this.employeeService = employeeService;
this.assembler = assembler;
}
@PostMapping()
public ResponseEntity<?> addEmployee(@RequestBody Employee employee, UriComponentsBuilder builder){
EntityModel<Employee> entityModel = this.assembler.toModel(this.employeeService.addEmployee(employee));
return ResponseEntity.created(entityModel.getRequiredLink(IanaLinkRelations.SELF).toUri()).body(entityModel);
}
...
There are more methods above, but addEmployee is the method i am trying to test.
Test:
@ExtendWith(SpringExtension.class)
@WebMvcTest(EmployeeController.class)
@AutoConfigureMockMvc
public class EmployeeControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private EmployeeService employeeService;
@MockBean
private EmployeeModelAssembler assembler;
@InjectMocks
private EmployeeController employeeController;
@Before
public void setUp(){
MockitoAnnotations.openMocks(this);
}
@Test
public void testAddEmployee() throws Exception {
String mockEmployeeJson =
" "firstName": "new",
" +
" "lastName": "Employee",
" +
" "emailAddress": "[email protected]",
" +
" "roll": "Software Engineer",
" +
" "team":
" +
" {
" +
" "teamId": 1
" +
" }
" +
"}";
mockMvc.perform(MockMvcRequestBuilders.post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(mockEmployeeJson)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
output:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /employees
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json", Content-Length:"171"]
Body = "firstName": "new",
"lastName": "Employee",
"emailAddress": "[email protected]",
"roll": "Software Engineer",
"team":
{
"teamId": 1
}
}
Session Attrs = {}
Handler:
Type = com.Ventura.Notifier.controller.EmployeeController
Method = com.Ventura.Notifier.controller.EmployeeController#addEmployee(Employee, UriComponentsBuilder)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotReadableException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 400
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
java.lang.AssertionError: Status expected:<200> but was:<400>
Expected :200
Actual :400
<Click to see difference>
Edit 1
changed the test to:
private Employee employee;
@BeforeEach
public void setUpEmployee(){
Team team = new Team();
team.setTeamId(1);
employee = new Employee();
employee.setTeam(team);
employee.setRoll("software developer");
employee.setLastName("Levi");
employee.setEmailAddress("[email protected]");
employee.setFirstName("David");
}
@Test
public void testAddEmployee() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
mockMvc.perform(MockMvcRequestBuilders.post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employee))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
but I am getting a null pointer exception.
Edit 2
I solved the null pointer exception, not sure why though. if anyone is interested in the solution:
The test:
@Test
public void testAddEmployee() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
mockMvc.perform(MockMvcRequestBuilders.post("/employees")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(employee))
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().is2xxSuccessful());
}
and i changed the return statement in the addEmployee method to:
return new ResponseEntity<>(entityModel, HttpStatus.CREATED);
question from:
https://stackoverflow.com/questions/65939134/how-to-use-correctly-mockmvc-to-test-post-method-in-junit