如何在单元测试SpringBoot中解析JWT令牌

Posted

技术标签:

【中文标题】如何在单元测试SpringBoot中解析JWT令牌【英文标题】:How to parse JWT token in unit tests SpringBoot 【发布时间】:2021-08-08 00:36:10 【问题描述】:

我有一个带有 Spring boot 的微服务设置和带有 JWT 的 OAuth 2。 我的 JWT 令牌中有其他字段。

我的大多数服务都调用一个静态方法,该方法具有令牌中附加字段的本地线程。 如何为此类服务编写单元测试? 即使我尝试注入一个模拟用户,它也不起作用,而且我找不到发送 JWT 的方法,因为我没有测试控制器。

代码:

SecurityUtils static Calss (also check the package for other relevant JWT handler) .

Example on a method that will call the static class (Line 79).

方法:

public CommonResponse saveUpdateProfile(ProfileRequest request) 

    String authUsername = SecurityUtils.getUsername();

    Optional<ProfileEntity> optionalProfile = findProfileByUsername(authUsername);

    ProfileEntity profile;
    if (optionalProfile.isPresent()) 
        profile = optionalProfile.get();
     else 
        profile = ProfileEntity.builder()
                .username(authUsername)
                .build();
    

    profile.setFirstName(request.getFirstName());
    profile.setLastName(request.getLastName());

    ProfileEntity savedProfile = profileRepository.save(profile);

    if (savedProfile == null) 
        throw new RuntimeException("Failed to save user in database");
    

    return CommonResponse.ok(savedProfile);

感谢所有帮助。

【问题讨论】:

你能显示一些相关的代码吗?您如何尝试注入用户。该静态方法的外观如何。它是如何从服务中调用的。测试的样子。这将有助于解决您的问题。现在有点太模糊了。 @Michal***owski 是的,抱歉,我添加了 github 参考,我没有添加测试,但您可以在 github 中找到它们,测试实现了我之前从 SecurityContext 检索的方法,我不能'还没有找到 JWT 的方法 【参考方案1】:

好的,这是使用静态方法时的常见问题。你不能轻易地覆盖它们,例如在测试中。我想我要做的就是把你的SecurityUtils 类变成一个服务并让它实现一个接口。然后将此接口注入到需要使用它的任何其他服务中,而不是调用静态方法。然后,您可以轻松地为您的测试提供另一个实现。

所以你会有类似的东西:

interface SecurityUtils 
    String getUsername();
    ...


@Service
class MySecurityUtils immplements SecurityUtils 
    private JwtToken getJwtToken() 
        return MySecurityContextHolder.getContext().getJwtToken();
    

    public String getUsername() 
        return getJwtToken().getUsername();
    
    ...


然后在单元测试中,您可以将SecurityUtils 的模拟实现注入您正在测试的任何类。

【讨论】:

我使用 mock-inline 对我的测试应用了一个修复来模拟静态方法。您认为使用您的解决方案更好吗?我读到人们不太喜欢模拟静态方法,所以我不确定。 这个解决方案绝对更干净。我认为只有在别无选择的情况下才应该模拟静态方法(例如,您使用来自 3rd 方库的方法)。您可以控制此代码,因此我认为最好使用接口并注入正确的实现。 好的,我明白了,谢谢你的解释。我会照你说的做的

以上是关于如何在单元测试SpringBoot中解析JWT令牌的主要内容,如果未能解决你的问题,请参考以下文章

单元测试 JWT 令牌过期:Django REST

为在 javascript 中使用 jwt 令牌的方法编写单元测试

使用 Web API 对 JWT 令牌进行单元测试

如何在 ASP.NET Core 中转储解析的 JWT 令牌?

如何通过 Java/Kotlin API 从 KeyCloak 请求 JWT 令牌

如何从请求中解析 JWT 令牌 [Next-Auth]