SpringBootTest MockMvc: andExpect status not throwing

Viewed 1208

I'm learning to write integration tests for a SpringBoot REST api, and when I send garbage data, the tests still pass. I would expect the ".andExpect(status().isCreated())" to throw an exception and fail the test, but it isn't?

@SpringBootTest
@AutoConfigureMockMvc
class BorrowerApplicationIntegrationTests {

  @Autowired
  private MockMvc mockMvc;

  @Autowired
  private ObjectMapper objectMapper;

  @Autowired
  private BookLoanDAO bookLoanDao;

  @Autowired
  private BorrowerController controller;


  @Test
  @Transactional
  void checkoutBook() throws Exception {
    BookLoanId bookLoanId = new BookLoanId(2, 2, 2); // This book does not exist in this branch

    mockMvc.perform(post("/borrowers/book/checkout")
            .contentType("application/json")
            .content(objectMapper.writeValueAsString(bookLoanId)))
            .andExpect(status().isCreated()); // The returned response is a 404 yet the test passes

    List<BookLoan> bookLoans = bookLoanDao.findAll().stream()
            .filter(l -> (
              l.getId().getBorrower().getId() == 1
              &&
              l.getId().getBook().getId() == 1
              &&
              l.getDateIn() == null))
            .collect(Collectors.toList());

    assertThat(bookLoans.size() > 0);
  }
}

When the tests run, the console prints:

org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND "Book with ID 2 is not available at branch with ID 2."

Why is the test passing even though the wrong response is being returned?

1 Answers

There are a number of things to try.

Set up MockMvc manually. I've had problems with @AutoConfigureMockMvc annotation and @Autowire MockMvc mockMcv setting up the beans incorrectly.

Setup http servlets in before each test and teardown after. Honestly, I've forgotten what they were for but they've solved some issues with the result defaulting 200/201 status.

Is the post() request using MockMvcRequestBuilders import; could be a wrong import used.


@ContextConfiguration // Replace @AutoConfigureMockMvc

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders
                .webAppContextSetup(context)
                .build();

        HttpServletRequest mockRequest = new MockHttpServletRequest();
        ServletRequestAttributes servletRequestAttributes = new ServletRequestAttributes(mockRequest);
        RequestContextHolder.setRequestAttributes(servletRequestAttributes);
    }

    @After
    public void tearDown() throws Exception {
        RequestContextHolder.resetRequestAttributes();
   }

    @Test
    public void testGetCv_NotFound() throws Exception {



    RequestBuilder request = MockMvcRequestBuilders
                 .post("/borrowers/book/checkout")
                .contentType("application/json")
                .content(objectMapper.writeValueAsString(bookLoanId));

        mockMvc.perform(request)
                .andExpect(status().isNotFound());
    }
Related