MockMvc启用Securtity验证和处理Response乱码问题

1,012 阅读2分钟

场景

最近公司针对于单元测试添加了MockMvcController层接口进行测试。

用的权限框架是Spring Securtity

问题:使用MockMvcController进行单元测试时直接略过了过滤器直接请求到对应的接口。

启用Securtity验证

现有实现

统一通过Before 创建 mockMvc 其它测试类直接使用该对象,代码如下:

@Before
public void before() {
    //可以对所有的controller来进行测试
    mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}

测试用例

@SneakyThrows
@Test
public void testSearchMemberInfo() {
    String url = "/searchMemberInfo?uId=&name=";
    String result = mockMvc.perform(MockMvcRequestBuilders.get(url)
            .contentType(MediaType.APPLICATION_JSON_VALUE))
            .andReturn()
            .getResponse()
            .getContentAsString(StandardCharsets.UTF_8);
    log.info("返回结果 =>{}", result);
}

因为系统是需要登录的,那么这个测试用例的正常流程应该得先进行token验证,通过验证后才能正确调用该接口。

在网上找了很多帖子最后还是自己摸索出来的,网上的解决办法有两个:

1、添加 @WebMvcTest 注解(@WebMvcTest@SpringBootTest 不能同时使用。并且添加这个注解之后Securtity相关的bean就不会注入,只会扫描定义的控制类还有一些基础代码并不会启动完整的应用程序上下文,使用这个注解会报加载不到上下文错误)

2、在创建mockMvc对象的时候使用apply(SecurityMockMvcConfigurers.springSecurity()) 方式,可能是版本问题这个解决的帖子离现在有点时间也无法解决当前问题。

解决办法(思路)

网上找了很多资料,然后看了一下MockMvc提供的方法,就有一个addFilter() 方法然后就试了试,好家伙直接就可以用了,修改后 @Before 代码如下:

@Autowired
private Filter springSecurityFilterChain;

@Before
public void before() {
    // 需要启用 Security 验证请使用这个
    mockMvc = MockMvcBuilders.webAppContextSetup(context)
                             .addFilter(springSecurityFilterChain)
                             .build();
}

加上 .addFilter() 直接就启用了拦截器亏我还上百度上谷歌搜了好多帖子都不行

解决Response乱码

开启验证后测试是没问题了,但返回打印的Response 内容中文乱码,处理办法在请求中设置字符集,在最后 .getContentAsString(StandardCharsets.UTF_8);

@SneakyThrows
@Test
public void testSearchMemberInfo() {
    String url = "/searchMemberInfo?uId=&name=";
    String result = mockMvc.perform(MockMvcRequestBuilders.get(url)
            .contentType(MediaType.APPLICATION_JSON_VALUE))
            .andReturn()
            .getResponse()
            .getContentAsString(StandardCharsets.UTF_8);
    log.info("返回结果 =>{}", result);
}