Sweta Sharma
Sweta Sharma

Reputation: 2764

java.lang.AssertionError: Status expected:<400> but was:<404>

Below is the controller method I'm trying to write a unit test for:

@GetMapping("/status/{uuid}")
    public ResponseEntity<StatusResponse> getStatusByUUID(@PathVariable(value = "uuid", required = true) String uuid) {
        if(uuid == null || uuid.isBlank() || uuid.isEmpty()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, Constant.UUID_VALIDATION_EXCEPTION);
        }
        logger.info("Get status request came in for UUID number: " + uuid);
        return Handler.getStatusByUUID(uuid);
    }

Below is the unite test I'm trying to run

@Test
    public void testGetStatusWhenUUIDIsEmpty() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/status/{uuid}", "")
                .characterEncoding("utf-8")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isBadRequest())
                .andExpect(result -> assertTrue(result.getResolvedException() instanceof ResponseStatusException));
                
    }

Below is the stack trace of the error

java.lang.AssertionError: Status expected:<400> but was:<404>
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
    at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:212)

Can someone help me with what I missed? Thank you for your time.

Upvotes: 0

Views: 5577

Answers (1)

Tim Tong
Tim Tong

Reputation: 324

By defining @GetMapping("/status/{uuid}"), you've defined an endpoint that requires an additional path. In the tests, however, the resulting URL is /status/ which does not match the pattern of the GetMapping hence the 404.

If you modify the GetMapping to also handle URIs without the additional path, it should trigger that method.

@GetMapping(value = {"/status", "/status/{uuid}"})
public ResponseEntity<StatusResponse> getStatusByUUID(@PathVariable(value = "uuid", required = false) String uuid) { ... }

Here was the test code I ran

@RestController
public class MyController {
  @GetMapping("/foo/{var}")
  public ResponseEntity<Void> foo(@PathVariable(value = "var") String var) {
    HttpStatus status = StringUtils.hasText(var) ? HttpStatus.OK : HttpStatus.BAD_REQUEST;
    return ResponseEntity.status(status).build();
  }

  @GetMapping(value = {"/bar", "/bar/{var}"})
  public ResponseEntity<Void> bar(@PathVariable(value = "var", required = false) String var) {
    HttpStatus status = StringUtils.hasText(var) ? HttpStatus.OK : HttpStatus.BAD_REQUEST;
    return ResponseEntity.status(status).build();
  }
}
public class MyTest {
  MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();

  @Test
  public void foo() {
    MvcResult result = mockMvc.perform(get("/foo/{var}", "")).andReturn();
    assertEquals(404, result.getResponse.getStatus());
  }

  @Test
  public void bar1() {
    MvcResult result = mockMvc.perform(get("/bar/{var}", "val")).andReturn();
    assertEquals(200, result.getResponse.getStatus());
  }

  @Test
  public void bar2() {
    MvcResult result = mockMvc.perform(get("/bar/{var}", "")).andReturn();
    assertEquals(400, result.getResponse.getStatus());
  }
}

Upvotes: 1

Related Questions