我很少有工作代码可以通过新的Spring Boot 1.4 MockMVc
以不同的方式设置@WebMvcTest
。我了解standaloneSetup方法。我想知道的是通过MockMvc
设置WebApplicationContext
和自动装配MockMvc
之间的区别。
代码段1:通过WebApplicationContext安装程序创建MockMvc
@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();
}
}
根据
WebMvcTest
API文档,默认情况下,用@WebMvcTest注释的测试还将自动配置Spring Security和MockMvc。因此,我希望此处显示401未经授权的状态代码,但测试通过时却带有200状态代码。接下来,我尝试自动连接
MockMvc
,但是除非添加@AutoConfigureMockMvc(secure=false)
或更新@WebMvcTest
注释以禁用安全性,否则测试会失败并显示401未经授权状态代码:@WebMvcTest(controllers = IndexController.class, secure = false)
以下是仅在明确禁用安全性之后传递的代码。
代码段2:通过自动装配的MockMvc
@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();
}
}
所以我的问题是:
为什么代码片段1在自动接线
MockMvc
时没有报告401未经授权的状态代码错误。还重申官方文档所说的内容。默认情况下,用@WebMvcTest注释的测试也将自动配置Spring Security和MockMvc。但是,在这种情况下,@WebMvcTest
似乎与自动配置Spring Security无关(因为代码段1通过且没有任何401错误)。最终归结为我如何设置MockMvc
。我在这里正确吗?两种方法之间的差异/目标是什么?
通过
@AutoConfigureMockMvc(secure=false)
禁用安全性与通过@WebMvcTest(controllers = IndexController.class, secure = false)
禁用安全性有何不同。首选哪种方法或何时(或在何处)使用它们? 最佳答案
我也遇到类似的问题。 @WebMvcTest使用基本身份验证自动配置Spring Security,但是我有一个WebSecurityConfig类扩展了WebSecurityConfigurerAdapter。在此类中,我禁用了基本身份验证并配置了令牌基础安全性。这意味着WebSecurityConfig类不用于配置Spring Security。
为了解决该问题,我在单元测试类中添加了@ContextConfiguration并添加了WebSecurityConfig类的依赖关系的模拟。
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = CategoryRestService.class)
@ContextConfiguration(classes={MjApplication.class, WebSecurityConfig.class})
public class CategoryRestServiceTest {
@MockBean
private CategoryRepository repository;
@MockBean
CurrentUserDetailsService currentUserDetailsService;
@MockBean
TokenAuthProvider tokenAuthProvider;
@Autowired
MockMvc mockMvc;
private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
@Test
public void getCategories() throws Exception {
Category category1 = new Category();
category1.setName("Test Category 1");
category1.setId(1L);
Category category2 = new Category();
category2.setName("Test Category 2");
category2.setId(2L);
List<Category> categoryList = new ArrayList<Category>();
categoryList.add(category1);
categoryList.add(category2);
given(this.repository.findAll())
.willReturn(categoryList);
mockMvc.perform(get("/public/rest/category"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$[0].id", is(1)))
.andExpect(jsonPath("$[0].name", is("Test Category 1")))
.andExpect(jsonPath("$[1].id", is(2)))
.andExpect(jsonPath("$[1].name", is("Test Category 2")));
}
}
关于spring-mvc - 在Spring Boot 1.4 MVC测试中使用@WebMvcTest设置MockMvc,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38168163/