当前位置: 首页 > 知识库问答 >
问题:

有人能帮我模拟一个返回对象的静态方法吗?这个静态方法存在于最后一个类中

湛财
2023-03-14

下面的事情我需要帮助,

我必须使用PowerMock/Mockito为一个方法编写一个JUnit,该方法调用外部jar中存在的最终类的静态方法。

我需要为其编写JUnit测试的方法是:

public class SomeClass {
    private PrivateKey privateKeyFromPkcs8(String privateKeyPem) throws IOException {
        Reader reader = new StringReader(privateKeyPem);
        Section section = PemReader.readFirstSectionAndClose(reader, "PRIVATE KEY");
        if (section == null) {
            throw new IOException("Invalid PKCS8 data.");
        }
        byte[] bytes = section.getBase64DecodedBytes();
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
        try {
            KeyFactory keyFactory = SecurityUtils.getRsaKeyFactory();
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            return privateKey;
        } catch (NoSuchAlgorithmException exception) {
        } catch (InvalidKeySpecException exception) {
        }
        throw new IOException("Unexpected exception reading PKCS data");
    }
}   

在上面的代码中PemReader是一个最终类,readFirstSectionAndClole(阅读器,“PRIVATE KEY”)PemReader中的静态方法。

我已经尝试编写如下所示的测试,但调试时节对象(节)显示为null。可能调用的是实际的代码(PemReader.readFirstSectionAndClose(reader,“PRIVATE KEY”)),而不是模拟。

@RunWith(PowerMockRunner.class)
@PrepareForTest({SomeClass.class,PemReader.class})
public class SomeClassTest {
    @InjectMocks
    SomeClass mockSomeClass;

    @Mock
    private Reader mockReader;

    @Mock
    private Section mockSection;

    @Test
    public void testPrivateKeyFromPkcs8() throws Exception {   
        PowerMockito.mockStatic(PemReader.class);
        Mockito.when(PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY")).thenReturn(mockSection);

        assertNotNull(mockSomeClass.privateKeyFromPkcs8(dummyPrivateKey));
    } 

 }

请帮助我使用powermockito/mockito编写Junit

共有1个答案

吕文林
2023-03-14

你必须准备最后的静态类。

这是一个使用JUnit的PowerMock注释的示例:

@RunWith(PowerMockRunner.class)
@PrepareForTest({PemReader.class})
public class PemReaderTest {

    @Mock
    private Reader mockReader;

    @Mock
    private Section mockSection;

    @Test
    public void testMockingStatic() {
        PowerMockito.mockStatic(PemReader.class);

        Mockito.when(PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY")).thenReturn(mockSection);

        Assert.assertEquals(mockSection, PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY"));
    }
}

为了完整起见,下面是PemReader的定义:

public final class PemReader {

    public static Section readFirstSectionAndClose(Reader reader, String key) {
        return null;
    }
}

以上测试通过,版本如下:

  • JUnit:4.12

更新1:根据您更新的问题。如果您只做以下更改,您的测试用例将通过(或至少在PemReader上调用。readFirstSectionAndClose将返回一些内容):

Mockito.when(PemReader.readFirstSectionAndClose(
    Mockito.any(Reader.class), 
    Mockito.eq("PRIVATE KEY"))
).thenReturn(mockSection);

当前测试用例中此指令的版本依赖于代码传递到readFirstSectionAndClose的StringReader与测试用例提供的模拟读取器之间的相等匹配。这些值不“相等”,因此模拟调用的期望值未得到满足,并且不会返回您的模拟节。

一些不相关的注释:

  • 不需要包含SomeClass。class在PrepareForTest中,您只需要在该注释中包含要模拟的类,因为SomeClass是您尝试测试的类,该类不需要模拟
 类似资料:
  • 我的测试用例是: 当我调用时,实际上不会调用此方法。如何在side中模拟方法的结果?

  • 问题内容: 我想从包含2个静态方法m1和m2的类中模拟静态方法m1。我希望方法m1返回一个对象。 我尝试了以下 1) 这将同时调用m1和m2,它们具有不同的返回类型,因此会给出返回类型不匹配错误。 2) 但是,执行m1时不会调用此方法。 3) 给出了我不能从http://code.google.com/p/powermock/wiki/MockitoUsage获得的,无法提供模拟部分的编译器错误。

  • 我想从一个包含两个静态方法m1和M2的类中模拟一个静态方法m1。并且我希望方法m1返回一个对象。 我尝试了以下操作 2)但在执行m1时不调用它。

  • 我正在设置模拟类的静态方法。我必须在一个带有注释的JUnit安装方法之前的JUnit中进行此操作。 我的目标是将类设置为调用真正的方法,但我显式模拟的方法除外。 基本上: 我遇到的问题是,如果提供了值,则在中,方法不幸地抛出。 因此,我不能简单地将调用real方法作为默认答案,如下所示: 在模拟了我感兴趣的方法的结果之后,我需要将默认答案设置为在所有其他静态方法上调用real方法。 这可能吗?

  • 使用JMockit模拟API,我如何模拟一个静态工厂方法来返回一个假的? 我的问题类似于如何模拟一个静态方法,该方法提供了一个用JMockit模拟的类的实例?,但我的合作者的工厂方法在我的测试环境中抛出了一个异常(这是正确的)。因此,我需要模拟工厂来消除有问题的操作。带有工厂方法的类是抽象的,并且只有包私有构造函数。

  • 问题内容: 我想模拟下一行: 这里的问题是newBigQueryClient方法返回的Bulder类是最终的。这意味着我既不能使用嘲讽也不可以使用powermockito来模拟它(它返回这样的异常:不能对最终类进行子类化),但是我需要返回适合于模拟它的构建方法的东西。有什么想法怎么做? 问题答案: 改善代码并使其更具可测试性的建议: 首先,您不会像您给我们的示例那样模拟 声明 。您可以模拟 对象