我可以测试我的JwtTokenAuthenticationFilter
类。如何使用Mockito&如何编写此类的测试用例。朱尼特?我只能测试此类。
我不明白如何模拟课程。
public class JwtTokenAuthenticationFilter extends OncePerRequestFilter {
private final JwtConfig jwtConfig;
public JwtTokenAuthenticationFilter(JwtConfig jwtConfig) {
this.jwtConfig = jwtConfig;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
System.out.println("Code is reachable");
// 1. get the authentication header. Tokens are supposed to be passed in the authentication header
String header = request.getHeader(jwtConfig.getHeader());
// 2. validate the header and check the prefix
if (header == null || !header.startsWith(jwtConfig.getPrefix())) {
chain.doFilter(request, response);
return;// If not valid, go to the next filter.
}
// If there is no token provided and hence the user won't be authenticated.
// It's Ok. Maybe the user accessing a public path or asking for a token.
// All secured paths that needs a token are already defined and secured in config class.
// And If user tried to access without access token, then he won't be authenticated and an exception will be thrown.
// 3. Get the token
String token = header.replace("Bearer","");
try { // exceptions might be thrown in creating the claims if for example the token is expired
// 4. Validate the token
Claims claims = Jwts.parser()
.setSigningKey(jwtConfig.getSecret().getBytes())
.parseClaimsJws(token)
.getBody();
String username = claims.getSubject();
if (username != null) {
@SuppressWarnings("unchecked")
List<String> authorities = (List<String>) claims.get(ApplicationConstant.tokenAuthorities);
List<GrantedAuthority> grantAuthorities = new ArrayList<GrantedAuthority>();
// 5. Create auth object
// UsernamePasswordAuthenticationToken:A built-in object, used by spring to represent the current authenticated / being authenticated user.
// It needs a list of authorities, which has type of GrantedAuthority interface, where SimpleGrantedAuthority is an implementation of that interface
for (String authName : authorities) {
grantAuthorities.add(new SimpleGrantedAuthority(authName));
}
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
username, null, grantAuthorities);
// 6. Authenticate the user
// Now, user is authenticated
SecurityContextHolder.getContext().setAuthentication(auth);
}
} catch (Exception e) {
// In case of failure. Make sure it's clear; so guarantee user won't be authenticated
SecurityContextHolder.clearContext();
}
// go to the next filter in the filter chain
chain.doFilter(request, response);
}
}
春季给您一些模拟:
-
MockHttpServletRequest
:HttpServletRequest
的模拟实现 -
MockHttpServletResponse
:HttpServletResponse
的模拟实现 -
MockFilterChain
:FilterChain
的模拟实现 -
MockFilterConfig
:如果FilterConfig
,则模拟实现
有关其他模拟的org.springframework.mock.web
软件包。
这是一些可以帮助您开始的代码:
@RunWith(SpringRunner.class)
public class JwtTokenAuthenticationFilterTest {
@Before
public void before() {
SecurityContextHolder.clearContext();
}
@After
public void after() {
SecurityContextHolder.clearContext();
}
@Test
@SneakyThrows
public void doFilterInternal_shouldPopulateSecurityContext_whenTokenIsValid() {
String token = issueTokenForUser("john.doe");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
request.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain filterChain = new MockFilterChain();
FilterConfig filterConfig = new MockFilterConfig();
JwtTokenAuthenticationFilter filter = new JwtTokenAuthenticationFilter();
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
assertThat(SecurityContextHolder.getContext().getAuthentication())
.satisfies(authentication -> {
assertThat(authentication).isNotNull();
assertThat(authentication.getName()).isEqualTo("john.doe");
});
}
private String issueTokenForUser(String username) {
return "xxxxx.yyyyy.zzzzz"; // Implement as per your needs
}
}
上面的代码使用assertj进行断言。