单元测试静态方法

新手上路,请多包涵

我正在尝试为此处解密的方法编写一个测试用例。

     private static Codec codec;

    static {
        try {
            codec = new Codec(encryptionType, encryptionKey, false, true, false);
        } catch (CodecException e) {
            throw new RuntimeException("Codec initialisation failed", e);
        }
    }

    public static String decrypt(final String toDecrypt) throws CodecException {
        String decrypted = codec.decryptFromBase64(toDecrypt);
        if (decrypted.endsWith(":")) {
            decrypted = decrypted.substring(0, decrypted.length() - 1);
        }
        return decrypted;
    }

测试用例:

     @Mock
    private Codec codec;
    @Test
    public void test_decrypt_Success() throws CodecException {
        when(codec.decryptFromBase64(TestConstants.toDecrypt)).thenReturn(TestConstants.decrypted);
        assertEquals(DocumentUtils.decrypt(TestConstants.toDecrypt), TestConstants.decrypted);
    }

由于这是一个静态方法,我无法在测试套件中注入该类的实例并模拟其编解码器。上面的代码按预期在 assert 处从编解码器库中抛出错误。

您测试此类静态方法的方法是什么?还是我根本不应该为此编写测试?

原文由 tanvi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 818
2 个回答

在 Java 中,静态方法并不是为了设置依赖而设计的。

因此,将依赖项转换为 mock 确实不自然。

您可以为该字段提供 static 设置器,例如:

 private static Codec codec;
public static void setCodec(Codec codec){
   this.codec = codec;
}

你可以设置一个模拟 setCodec(...) 但是呃…

但是忘了,把事情做好:重构代码以删除所有静态并引入一个设置编解码器的构造函数。

 private Codec codec;
public MyClassUnderTest(Codec codec){
   this.codec codec;
}

IOC 可以在这里帮助使被测类成为单例并简化依赖注入。

如果在您的情况下不可能,Java 5 枚举至少可以帮助您解决单例问题。

原文由 davidxxx 发布,翻译遵循 CC BY-SA 4.0 许可协议

有许多不同的捷径可以实现相同的目标(正如评论和其他答案中所指出的),但从长远来看,并不是所有的方法都是好的。

我建议创建一个实现解密功能的单例类。所以,你不必创建多个实例,也不需要静态方法来解密,你可以一次又一次地轻松注入你的编解码器(我假设你没有多种类型的编解码器根据您的意见。但是,如果您这样做,则应相应地调整功能)。

更多参考: Why use a singleton instead of static methods?

关于为什么要小心使用静态的参考:- 为什么静态变量被认为是邪恶的?

原文由 Ankur Chrungoo 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题