Search code examples
javaspringunit-testingspring-mvcspring-test-mvc

When try to test post() rest endpoint see: json can not be null or empty


If I try to test the post() endpoint, I see:

java.lang.AssertionError: No value at JSON path "$.firstName"

Caused by: java.lang.IllegalArgumentException: json can not be null or empty

But with the test for the get() all work fine. And in the postTest() the result for status is correct. Where is my mistaker? Is it correct way to test the rest controller in this style?

@RunWith(MockitoJUnitRunner.Silent.class)
public class Temp {
    private final Employee successfullyRegisteredEmployee = new Employee(2L, "Iven");
    private final Employee employeeGetById = new Employee(2L, "Iven");


    @Mock
    private EmployeeServiceImpl serviceMock;

    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(new EmployeeControllerImpl( serviceMock))
                .build();
    }


    @Test
    public void getTest() throws Exception {
        when(serviceMock.getEmployee(2L)).thenReturn(employeeGetById);

        mockMvc.perform(get("/employee/get/2"))
                .andExpect(status().is(200))
                .andExpect(content().json(("{'firstName':'Iven'}")));

        verify(serviceMock).getEmployee(2L);
    }



    @Test
    public void postTest() throws Exception {
        String json = "{\n" +
                "  \"firstName\": \"Iven\"\n" 
                "}";
        when(serviceMock.register(employeeForRegister)).thenReturn(successfullyRegisteredEmployee);

        mockMvc.perform( MockMvcRequestBuilders
                .post("/employee/register")
                .content(json)
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().is(201))
                .andExpect(jsonPath("$.firstName", Matchers.is("Iven")));

    }
}

@RestController
@RequestMapping("/employee")
public class EmployeeControllerImpl implements EmployeeController {
    private final EmployeeService service;

    public EmployeeControllerImpl(EmployeeService service) {
        this.service = service;
    }

    @PostMapping(path = "/register",
            consumes = "application/json",
            produces = "application/json"
    )
    public ResponseEntity<Employee> registerEmployee(@Valid @RequestBody Employee employee) {
        Employee registeredEmployee = service.register(employee);
        return ResponseEntity.status(201).body(registeredEmployee);
    }
}

Solution

  • Seems like problem could be with when(serviceMock.register(employeeForRegister)).thenReturn(successfullyRegisteredEmployee);.

    Did you try to have breakpoint on return ResponseEntity.status(201).body(registeredEmployee); to check if registeredEmployee is actually filled? If it's empty then try replacing mock with when(serviceMock.register(any())).thenReturn(successfullyRegisteredEmployee); and if it works that means either equals() method is not overridden for Employee or comparison just fails.