[英]Testing access token filter
我創建了一個 Bearer 令牌創建者,當我編寫它的測試時,測試總是失敗並返回 nullPointerException 有什么問題?
注意:不記名令牌語法類似於 [Bearer {someEncodedCharacter}]。
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
@SpringBootTest
public class JwtTokenFilterTest {
@MockBean
private HttpServletRequest httpRequest;
@MockBean
private TokenManager tokenManagerTester;
@MockBean
private Authentication authentication;
@MockBean
private SecurityContext securityContext;
@MockBean
private HttpServletResponse httpResponse;
@MockBean
private FilterChain filterChain;
@Test
public void givenHttpServletRequestandHttpServletResponseandFilterChainDoFilterInternal()
throws ServletException, IOException {
String token="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhYmMxMjMiLCJpc3MiOiJ3d3cuYWJjLmNvbSIsImlhdCI6MTU5NDY0MTUzNywiZXhwIjoxNTk0NjQxODM3fQ.GHzVaQW_tvqo8HlDmoXzZ8WIYGcLHciLOSMFxsZUOsY";
Mockito.when(httpRequest.getHeader("Authorization")).thenReturn("Bearer "+token);
Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
Mockito.when(tokenManagerTester.tokenValidate(Mockito.anyString())).thenReturn(true);
Mockito.when(tokenManagerTester
.getUsernameToken(token))
.thenReturn("abc123");
JwtTokenFilter filter=new JwtTokenFilter();
filter.doFilterInternal(httpRequest, httpResponse, filterChain);
Mockito.verify(filterChain,Mockito.times(1));
}
}
這是 JwtfFilter:
@Component
public class JwtTokenFilter extends OncePerRequestFilter {
@Autowired
private TokenManager tokenManager;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
@NotNull HttpServletResponse httpServletResponse,
@NotNull FilterChain filterChain) throws ServletException, IOException {
/**
* We are parsing our token in two pieces and we process the second
* "Bearer hvs231asas2355"
*/
final String authHeader = httpServletRequest.getHeader("Authorization");
/* */
String username = null;
String token = null;
if (authHeader != null && authHeader.contains("Bearer")) {
token = authHeader.substring(7);
try {
username = tokenManager.getUsernameToken(token);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
if (tokenManager.tokenValidate(token)) {
UsernamePasswordAuthenticationToken upassToken =
new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
upassToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
SecurityContextHolder.getContext().setAuthentication(upassToken);
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
注2:我認為如果我控制 filterChain.dofilter 我可以看到該方法是正確的。 出於這個原因,我寫了 Mockito.verify(filterChain,Mockito.times(1));
您在測試 class 的頂部缺少@SpringBootTest或@WebMvcTest注釋。 這就是 Spring 不模擬依賴 bean 的原因。
或者您可以使用 Mockito:
@RunWith(MockitoJUnitRunner.class)
public class JwtTokenFilterTest {
@Mock
private HttpServletRequest httpRequest;
@Mock
private TokenManager tokenManagerTester;
@Mock
private Authentication authentication;
@Mock
private SecurityContext securityContext;
@Mock
private HttpServletResponse httpResponse;
@Mock
private FilterChain filterChain;
@InjectMocks
private JwtTokenFilter filter=new JwtTokenFilter();
@Test
public void givenHttpServletRequestandHttpServletResponseandFilterChainDoFilterInternal()
throws ServletException, IOException {
String token="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhYmMxMjMiLCJpc3MiOiJ3d3cuYWJjLmNvbSIsImlhdCI6MTU5NDY0MTUzNywiZXhwIjoxNTk0NjQxODM3fQ.GHzVaQW_tvqo8HlDmoXzZ8WIYGcLHciLOSMFxsZUOsY";
Mockito.when(httpRequest.getHeader("Authorization")).thenReturn("Bearer "+token);
Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
Mockito.when(tokenManagerTester.tokenValidate(Mockito.anyString())).thenReturn(true);
Mockito.when(tokenManagerTester
.getUsernameToken(token))
.thenReturn("abc123");
filter.doFilterInternal(httpRequest, httpResponse, filterChain);
Mockito.verify(filterChain,Mockito.times(1));
}
}
問題是我使用了 MockBean 而不是 Mock。
private static HttpServletRequest httpRequest;
private static TokenManager tokenManagerTester;
private static Authentication authentication;
private static SecurityContext securityContext;
private static HttpServletResponse httpResponse;
private static FilterChain filterChain;
@BeforeClass
public static void setUp(){
httpResponse = mock(HttpServletResponse.class);
filterChain=mock(FilterChain.class);
securityContext=mock(SecurityContext.class);
authentication=mock(Authentication.class);
tokenManagerTester=mock(TokenManager.class);
httpRequest=mock(HttpServletRequest.class);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.