You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何Mock Authentication.getAuthorities()?编译错误解决方法

问题分析与解决

场景背景

我实现了一个Spring OncePerRequestFilter 过滤器,核心逻辑是根据用户权限判断是否处理请求,代码如下:

过滤器核心方法

@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException {
    final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null && containsRole(auth, "SpecificRole")) {
        doThingsWithTheRequest(request);
    }
    filterChain.doFilter(request, response);
}

权限判断方法

protected boolean containsRole(final Authentication auth, final String role) {
    for (final GrantedAuthority ga : auth.getAuthorities()) {
        if (ga.getAuthority().equals(role)) {
            return true;
        }
    }
    return false;
}

为测试该逻辑,我编写了JUnit测试,尝试Mock Authentication.getAuthorities() 让权限判断返回true,但遇到编译错误:

测试代码

@Test
public void test() throws ServletException, IOException, CommerceCartRestorationException {

    SecurityContext securityContextMock = mock(SecurityContext.class);
    Authentication authenticationMock = mock(Authentication.class);

    SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("MyRole");
    Collection<SimpleGrantedAuthority> authCollection = Collections.singleton(simpleGrantedAuthority);

    // 此处出现编译错误
    when(authenticationMock.getAuthorities()).thenReturn(authCollection);
    when(securityContextMock.getAuthentication()).thenReturn(authenticationMock);

    SecurityContextHolder.setContext(securityContextMock);
    
    testObj.doFilterInternal(httpServletRequestMock, httpServletResponseMock, filterChainMock);
}

错误信息:

Cannot resolve method 'thenReturn(Collection)'

已知Authentication.getAuthorities()返回Collection<? extends GrantedAuthority>,SimpleGrantedAuthority实现了GrantedAuthority接口,且无法使用spring-security-test依赖及@WithMockUser注解。


错误原因

Mockito的when...thenReturn语法在处理带通配符的泛型(Collection<? extends GrantedAuthority>)时,无法自动完成类型推断。虽然Collection<SimpleGrantedAuthority>是Collection<? extends GrantedAuthority>的子类型,但编译器无法识别两者的兼容性,导致找不到匹配的thenReturn方法重载。

修复方案

提供三种可行的修复方式:

1. 调整集合的泛型类型

将集合的泛型声明为GrantedAuthority,使其与方法返回的泛型类型完全匹配:

SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("MyRole");
Collection<GrantedAuthority> authCollection = Collections.singleton(simpleGrantedAuthority);

2. 显式指定thenReturn的泛型参数

通过泛型参数明确告知编译器返回类型,帮助完成类型推断:

when(authenticationMock.getAuthorities()).<Collection<? extends GrantedAuthority>>thenReturn(authCollection);

3. 使用doReturn语法替代

Mockito的doReturn语法对泛型的兼容性更好,可以绕过类型推断问题:

doReturn(authCollection).when(authenticationMock).getAuthorities();

内容的提问来源于stack exchange,提问作者Niklas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:53:20