簡體   English   中英

測試訪問令牌過濾器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM