猿问

单元测试静态方法

我正在尝试在这里为方法解密编写一个测试用例。


    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 处从编解码器库中引发错误。


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


慕无忌1623718
浏览 190回答 3
3回答

LEATH

在 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 枚举至少可以帮助您解决单例问题。

江户川乱折腾

有许多不同的捷径可以实现相同的目标(如评论和其他答案中所指出的那样),但从长远来看,并非所有这些方法都是好的。我建议创建一个实现 Decrypt 功能的 Singleton 类。因此,您不必创建多个实例,也不需要使用静态方法进行解密,并且您可以更轻松地注入您的编解码器(我假设您没有多种类型的编解码器)根据您的评论。但是,如果您这样做,则应相应地调整功能)。

心有法竹

根据我在这些情况下的经验,我只是在 @Before 方法中准备所有实例:private Codec codec;@Beforepublic void setup() throws CodecException {  codec = new Codec(encryptionType, encryptionKey, false, true, false);}
随时随地看视频慕课网APP

相关分类

Java
我要回答