PowerMockito模拟单个静态方法并返回另一个静态方法内的对象

8
我已经编写了测试用例,使用PowerMockito的mockStatic功能模拟静态类和方法。但我正在努力模拟另一个静态方法内部的一个静态方法。我确实看到了一些例子,包括这个,但它们中没有一个真正帮助我或者我没有理解实际的功能?(我一无所知)。
例如,我有一个如下的类,完整代码在这里
public static byte[] encrypt(File file, byte[] publicKey, boolean verify) throws Exception {
        //some logic here
        PGPPublicKey encryptionKey = OpenPgpUtility.readPublicKey(new ByteArrayInputStream(publicKey));
        //some other logic here
}

public/private static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {
 //Impl of this method is here
}

我的测试用例是:

@Test
    public void testEncrypt() throws Exception {
        File mockFile = Mockito.mock(File.class);
        byte[] publicKey = { 'Z', 'G', 'V', 'j', 'b', '2', 'R', 'l', 'Z', 'F', 'B', 'L', 'Z', 'X', 'k', '=' };
        boolean flag = false;

        PGPPublicKey mockPGPPublicKey = Mockito.mock(PGPPublicKey.class);
        InputStream mockInputStream = Mockito.mock(InputStream.class);

        PowerMockito.mockStatic(OpenPgpUtility.class);

        PowerMockito.when(OpenPgpUtility.readPublicKey(mockInputStream)).thenReturn(mockPGPPublicKey);

        System.out.println("Hashcode for PGPPublicKey: " + OpenPgpUtility.readPublicKey(mockInputStream));
        System.out.println("Hashcode for Encrypt: " + OpenPgpUtility.encrypt(mockFile, publicKey, flag));
    }

当我调用 OpenPgpUtility.encrypt(mockFile, publicKey, flag) 方法时,实际上并没有调用该方法。 如何在 encrypt(...) 方法内模拟 readPublicKey(...) 方法的结果?

你的测试类使用了哪种方法?这就是你应该模拟的方法。没有必要模拟私有方法,因为你可以模拟公共接口。 - Turing85
我正在测试encrypt方法的行为,该方法具有另一个静态方法readPublicKey - Extreme
为什么要模拟同一类中的方法?编写测试以测试readPublicKey(...),并编写encrypt(...)的测试。它仍然是相同的被测试单元,因此不应使用模拟。模拟用于消除对外部依赖项(例如数据库或未知接口实现)的影响。 - Turing85
我对单元测试还很陌生,但我理解的是,当我测试一个方法的行为时,我需要模拟所有外部依赖项(包括同一类中的所有方法)。我错了吗? - Extreme
相当是的。外部依赖是 - 外部的。一个类是一个单元,应该作为这样进行测试。如果你为两个方法编写了测试,并且一些“更新”将破坏readPublicKey,那么很可能一些对两个方法的测试将变为红色。 - Turing85
在这种情况下,我现在正在修复那些已经损坏/更新的方法的测试用例。 - Extreme
1个回答

11

我在某人的帖子中在SOF中找到了解决方案。

在我的情况下,我使用了与下面相同的PowerMockito的部分模拟。

PowerMockito.stub(PowerMockito.method(OpenPgpUtility.class, "readPublicKey", InputStream.class)).toReturn(mockPGPPublicKey);

这让我可以模拟readPublicKey()但实际调用encrypt()


2
你用这个解决方案救了我的一天。 - Nishant Lakhara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接