提问人:Niklas 提问时间:10/22/2023 更新时间:10/22/2023 访问量:39
如何模拟 Authentication.getAuthorities()
How do I mock Authentication.getAuthorities()
问:
我有一个Spring OncePerRequestFilter过滤器,其中包含doFilterInternal的实现,如下所示:
@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);
}
containsRole 如下所示:
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测试,我想模拟Authentication.getAuthorities(),以便containsRole将返回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);
}
我收到编译器错误
无法解析方法“thenReturn(Collection)”
在这一行:
when(authenticationMock.getAuthorities()).thenReturn(authCollection);
getAuthorities 返回此
Collection<? extends GrantedAuthority>
SimpleGrantedAuthority 实现 GrantedAuthority 接口
所以问题是我为什么以及如何解决它?
我见过类似的问题,答案是向spring-security-test添加依赖项并使用@WithMockUser但恐怕使用spring-security-test不是一个选项
答:
1赞
knittl
10/22/2023
#1
Authentication#getAuthorities
具有返回类型,这是一个通配符类型。您不知道实际类型是什么,因此不能为其赋值或将其用作其他方法中的参数。Collection<? extends GrantedAuthority>
一个简单的解决方法是强制转换为原始集合类型:
Mockito.when(authenticationMock.getAuthorities())
.thenReturn((Collection) authorityCollection);
但更可持续的解决方案是首先不要模拟接口,而是使用专门实现来支持测试的实现:TestingAuthenticationToken
:Authentication
final Authentication authentication = new TestingAuthenticationToken(
null, // principal
null, // credentials
"MyRole"); // authority roles
评论
containsRole
doFilterInternal
containsRole
Spy