I have few working code to set up MockMVc
in different ways with the new Spring Boot 1.4 @WebMvcTest
. I understand the standaloneSetup approach. What I want to know is the difference between setting up MockMvc
through WebApplicationContext
and by autowiring MockMvc
.
Code Snippet 1: MockMvc through WebApplicationContext Setup
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = ProductController.class)
public class ProductControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@MockBean
private ProductService productServiceMock;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void testShowProduct() throws Exception {
Product product1 = new Product();
/*Code to initialize product1*/
when(productServiceMock.getProductById(1)).thenReturn(product1);
MvcResult result = mockMvc.perform(get("/product/{id}/", 1))
.andExpect(status().isOk())
/*Other expectations*/
.andReturn();
}
}
As per WebMvcTest
API documentation, By default, tests annotated with @WebMvcTest will also auto-configure Spring Security and MockMvc. So, I expected a 401 Unauthorized status code here, but the test passes with a 200 status code.
Next, I tried auto wiring MockMvc
, but the test fails with 401 Unauthorized status code, unless I add @AutoConfigureMockMvc(secure=false)
or update the @WebMvcTest
annotation to disable security:
@WebMvcTest(controllers = IndexController.class, secure = false)
Following is the code that passes ONLY AFTER explicitly disabling security.
Code Snippet 2: MockMvc through Autowiring
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = ProductController.class)
@AutoConfigureMockMvc(secure=false)
public class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@MockBean
private ProductService productServiceMock;
@Test
public void testShowProduct() throws Exception {
Product product1 = new Product();
/*Code to initialize product1*/
when(productServiceMock.getProductById(1)).thenReturn(product1);
MvcResult result = mockMvc.perform(get("/product/{id}/", 1))
.andExpect(status().isOk())
/*Other expectations*/
.andReturn();
}
}
So my questions are:
Why didn't Code snippet 1 report a a 401 Unauthorized status code error while auto wiring
MockMvc
did. Also reiterating what the official doc says By default, tests annotated with @WebMvcTest will also auto-configure Spring Security and MockMvc. But, in this case it appears@WebMvcTest
has nothing to do with auto-configuring Spring Security (Because Code Snippet 1 passes without any 401 error). It finally boils down to how I set up theMockMvc
. Am I correct here?What are the differences/objectives between/of both the approaches?
How does disabling security via
@AutoConfigureMockMvc(secure=false)
differs from doing through@WebMvcTest(controllers = IndexController.class, secure = false)
. Which one is the preferred approached or when (or where) to use them?