Integration test fails when attempting to auto configure via AutoConfigureMockMvc

Viewed 346

I am writing a simple test for a controller endpoint.

It works fine when I do the following.

@SpringBootTest
@ContextConfiguration(classes = {
        HomeController.class,
        HomeControllerTest.class
})
class HomeControllerTest {

    @Autowired
    private WebApplicationContext webApplicationContext;

    private static final String URL = "/a";
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void test() throws Exception {

        MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();

        Request request = new Request();

        mockMvc.perform(post(URL)
                .contentType("application/json")
                .content(objectMapper.writeValueAsString(request))
                .andExpect(status().isOk());
    }
}

But I do not want to have to create the mockMvc and concern with webApplicationContext.
Thus instead, attempting to use @AutoConfigureMockMvc instead as follows.
But this doesn't work. Fails with following error.

java.lang.AssertionError: Status expected:<200> but was:<403> Expected :200 Actual :403

What am I doing wrong?

My attempt which throws above error.

@SpringBootTest
@AutoConfigureMockMvc // using this annotation instead
@ContextConfiguration(classes = {
        HomeController.class,
        HomeControllerTest.class
})
class HomeControllerTest {

    // wiring mockMvc instead
    // no webApplicationContext autowired
    @Autowired
    private MockMvc mockMvc;

    private static final String URL = "/a";
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void test() throws Exception {

        Request request = new Request();

        mockMvc.perform(post(URL)
                .contentType("application/json")
                .content(objectMapper.writeValueAsString(request))
                .andExpect(status().isOk());
    }
}
1 Answers

Try create test like this exemple it is better.

 @SpringBootTest
 @AutoConfigureMockMvc
 public class HomeControllerTest 

    private ObjectMapper mapper;
    private MyControler myController;
    private ServiceInSideConttroler service;
    add your atributes
    
    @Before
    public init(){
    this.mapper = new ObjectMapperConfiguration().mapper();
    this.service = mock(ServiceInSideConttroler.class);
    this.myController = new MyController(service);
    }

    @Test
    public void test() throws Exception {
          // exemple how mock reponse from any service or repository.
         when(service.findById(any(Long.class)))
          .thenReturn(Optional.of(budget));

       Object resp =  myController.save(mockben());
         ...... 
         aserts(resp)
    }
}

Remember, to work with the tests like this, do not use @Authwired in the attributes, only in the constructor of the classes annotated with @service, @componet, @controller etc .... that is, any class controlled by Spring that will use dependecia injection. Also rember asserts your reponse.

Related