Home > Back-end >  WebApplicationContext is required - MockMVC
WebApplicationContext is required - MockMVC

Time:10-11

I'm trying to unit test a controller class, but have been stuck with the following error. I tried changing notations and following some online tutorials but it has not been working, I always get this same error. Here's the stackTrace:

java.lang.IllegalArgumentException: WebApplicationContext is required
at org.springframework.util.Assert.notNull(Assert.java:201)
at org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder.<init>(DefaultMockMvcBuilder.java:52)
at org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup(MockMvcBuilders.java:51)
at br.com.gwcloud.smartplace.catalog.controller.test.ItemControllerTest.setUp(ItemControllerTest.java:66)
...

And this is my controller test class:

@SpringBootTest
@WebMvcTest(controllers = ItemController.class)

@ActiveProfiles("test")
@WebAppConfiguration
public class ItemControllerTest {

    @MockBean
    private ItemRepository ir;
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private WebApplicationContext webApplicationContext;
    @Autowired
    private ObjectMapper objectMapper;

    @Before
    public void setUp() {
        this.mockMvc = webAppContextSetup(webApplicationContext).build();
        DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.webApplicationContext);
        this.mockMvc = builder.build();
    }

    @Test
    public void shouldCreateNewItem() throws Exception {
        
        ItemDTO itemDTO = new ItemDTO();
        itemDTO.setName("Leo");
        itemDTO.setDescription("abc description");
        itemDTO.setEnabled(true);
        itemDTO.setPartNumber("leo123");
        Item item = itemDTO.convertToEntity(modelMapper);
        
          mockMvc.perform(
                    post("/api/item/").contentType(
                        MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(item))).andExpect(
                    status().isOk());
    }

}

CodePudding user response:

The error you are encountering might be solved by adding:

@RunWith(SpringRunner.class)

Just below @SpringBootTest. Or you could instead extend AbstractJUnit4SpringContextTests.

Another problem is that the WebApplicationContext might not be available in an @Before annotated method. Try moving it into the test method itself.

That said, I usually avoid unit testing controllers, since I don't put any business logic in them. The stuff controllers do is specifying paths, mapping request arguments, error handling (although that is better handled in a separate ControllerAdvice class), setting up the view model and view target etc. These are all what I call 'plumbing' and tie in heavily with the framework you are using. I don't unit test that.

Instead, this plumbing can be validated by having a couple of high level integration tests that actually do a remote call to the controller and execute a complete flow, including all the plumbing.

Any business logic should be taken outside of the controller (typically in services) and unit tested there, in isolation.

CodePudding user response:

Have you tried removing @SpringBootTest and @WebAppConfiguration. If you are only interested in testing controller you don't need a full-blown application through these annotations.

  • Related