【问题标题】:Junit for generateToken() method for JWT in Springboot用于 Springboot 中 JWT 的 generateToken() 方法的 Junit
【发布时间】:2022-10-05 00:33:16
【问题描述】:

公共字符串 generateToken(最终字符串 id){

Claims claims = Jwts.claims().setSubject(id);
long nowMillis = System.currentTimeMillis();
long expMillis = nowMillis + tokenValidity;
Date exp = new Date(expMillis);

return Jwts.builder().setClaims(claims).setIssuedAt(new Date(nowMillis)).setExpiration(exp)
        .signWith(SignatureAlgorithm.HS512, jwtSecret).compact();

}

现在我想为这种方法编写Junit,我正在尝试如下,但我收到错误

 @Test
    @Order(1)
    public void test_generateToken() throws JwtTokenMalformedException, JwtTokenMissingException {
        final String subject_id = "123456789";
        final Long tokenValidity = 180000L;
        final String jwtSecret = "jwtSecret";

        when(Jwts.claims().setSubject(subject_id)).thenReturn(new DefaultClaims()); //** line no: 10
      
        when(Jwts.builder().setClaims(claims).setIssuedAt(new Date(nowMillis)).setExpiration(exp)
                .signWith(SignatureAlgorithm.HS512, jwtSecret).compact()).thenReturn(new String());
    }

在第 10 行出现错误:org.mockito.exceptions.misusing.MissingMethodInvocationException: when() 需要一个参数,该参数必须是“模拟方法调用”。 例如: when(mock.getArticles()).thenReturn(articles);

此外,可能会出现此错误,因为:

  1. 您存根以下任一方法:final/private/equals()/hashCode() 方法。 那些方法不能被存根/验证。 不支持在非公共父类上声明的模拟方法。
  2. 在 when() 中,您不会在模拟上调用方法,而是在其他对象上调用方法。

【问题讨论】:

  • 有人可以建议如何为这种方法编写测试用例吗?

标签: spring-boot junit mockito


【解决方案1】:

您的代码中需要解决两个问题:模拟静态方法和对模拟对象的多个链式调用。请在下面找到带有内联 cmets 的代码以及一些参考资料以供进一步阅读。重要提示:应使用mockito-inline(请参阅下面的文档链接)。

void test_generateToken() {
    var tested = new TestedClass();
    var jwtSecret = "jwtSecret";
    var claims = new DefaultClaims();
    var mockedValue = "mocked value";
    var builder = mock(Jwts.JwtsBuilder.class, RETURNS_DEEP_STUBS);

    try (var mockedStatic = mockStatic(Jwts.class)) {
        // to mock static methods the object returned from the mockStatic method should be used
        mockedStatic.when(Jwts::claims)
                    .thenReturn(claims);
        mockedStatic.when(Jwts::builder)
                    .thenReturn(builder);
        // here we're not mocking static methods, so a standard when method is used
        // thanks to RETURNS_DEEP_STUBS we can mock a chain of method calls
        when(builder.setClaims(claims)
                    // other argument matchers like argThat() can be used here
                    .setIssuedAt(any())
                    .setExpiration(any())
                    .signWith(SignatureAlgorithm.HS512, jwtSecret)
                    .compact())
                .thenReturn(mockedValue);

        var result = tested.generateToken("value");

        assertEquals(mockedValue, result);
    }
}

我创建了a commit in a GitHub repository,您可以在其中找到上面的代码以及mockito-inline 依赖项引用和一些代表您问题中缺少的代码的假类(这并不重要,因为它都是模拟的)。示例中显示的测试通过。

【讨论】:

    猜你喜欢
    • 2019-11-27
    • 2021-11-05
    • 2019-12-01
    • 2022-11-19
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多