Как я могу протестировать свой класс JwtAuthentication с помощью JUnit и Mockito?

Я могу проверить свой JwtTokenAuthenticationFilter класс. Как я могу написать тестовые примеры этого класса, используя Mockito и JUnit? Я могу только проверить этот класс.

Я не понимаю, как я могу издеваться над классом.

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);
    }
}

В чем твоя проблема? Чего ты не знаешь? Покажите свой тестовый класс.

dur 22.05.2019 16:14
0
1
3 451
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Spring дает вам несколько насмешек:

  • 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 для утверждений.

Другие вопросы по теме

Похожие вопросы

Использование коллекторов для группировки по одному полю, подсчета и добавления другого значения поля
Как с помощью Spring Security перенаправить зарегистрированного пользователя на его главную страницу, а незарегистрированного пользователя на другую
Axon Как я могу добавить прослушиватель/перехватчик событий для перехвата событий до того, как они достигнут своих обработчиков?
Как решить ошибку HHH000346, используя hibernate 5 и mysql?
Ожидаемое значение выражения jsonPath, но возвращаемый список значений
Как выполнить модульное тестирование (вставить) уровень поставщика данных в Spring Framework?
Как опубликовать список bean-компонентов с помощью RestTemplate, но bean-компонент должен быть массивом байтов?
Почему мой работающий интерфейс зацикливает мою очередь Продолжить здесь
Как мы можем сделать асинхронный вызов API REST в Java?
Как интегрировать фабричный метод, который принимает Class<T> и производит T в Spring