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

mockito,如何模拟作为容器类成员的类

连文栋
2023-03-14

使用mockito inline如何测试静态函数(使用stubing其他静态函数)或mock/stub某些内部依赖类?

以下是示例:

具有内部依赖于java的类Util。安全消息摘要

package java.security;
public abstract class MessageDigest extends MessageDigestSpi
    ... ...
    public byte[] digest() {
       
        byte[] result = engineDigest();       
        return result;
    }
}

容器类有一些静态函数要测试

public class Util {

    public static byte[] getStringDigest(@NonNull String text, @NonNull String algorithm, @NonNull String charSet) {
        if (text == null) {
            return null;
        }
        MessageDigest messageDigest;  //<== depend on 
        try {
            messageDigest = MessageDigest.getInstance(algorithm);
            messageDigest.update(text.getBytes(charSet));
        } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
            return null;
        }

        return messageDigest.digest();
    }

    public static String generateId(@NonNull String s) {
        byte[] sha1Byte = getStringDigest(s, "SHA-1", "UTF-8");
        if (sha1Byte == null) {
            return s;
        }
        // otherwise build the id
        String id = buildId(sha1Byte);
        return id;
    }
}

希望测试Utils.generateId(@NonNull String s),并将getStringDigest()返回为null,以便somettext有望返回。

由于它是静态函数,因此使用powermock进行了测试。

@Test
public test_util_1{
        PowerMockito.mockStatic(MessageDigest.class);
        String sometext = "sometext";
        PowerMockito.when(Util.getStringDigest(sometext, "SHA-1", "UTF-8")).thenReturn(null);
        assertEquals(sometext, Util.generateId(sometext));

}

当使用模拟存根时。调用getStringDigest(),返回null。它工作得很好。

现在mockito-inline支持测试静态函数(在测试kotlin等时与powermockito2混合存在问题),因此取消了powermock。

使用mockito inline 3.8.0进行了尝试

    @Test
    public void test_util_1() {

        String sometext = "sometext";
        try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
            utilMoc.when(() -> Util.getStringDigest(sometext, "SHA-1", "UTF-8"))
                    .thenReturn(null);

            assertEquals(sometext, Util.generateId(sometext));

        }

获取错误:

java.lang.AssertionError: Unexpected value 
Expected :sometext
Actual   :null

Util。generateId(sometext)返回null(而不是sometext)。

使用assertEquals(sometext,sutilMoc.generateId(sometext))时 它无法编译并表示无法解析生成ID()。

如何使用mockito内联测试静态函数?

或者,如果有办法模拟/存根依赖的抽象类MessageDigest,存根将返回null,但不知道这是否可能?

共有1个答案

墨高杰
2023-03-14

找到了使测试正常工作的方法(使用。thenCallRealMethod()),

但是仍然没有找到一种方法来模拟在静态函数中实例化的依赖类。如果有人知道解决方案吗?

    @Test
    public void test_util_1() {

        String sometext = "sometext";
        try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
            utilMoc.when(() -> Util.getStringDigest(anyString(), anyString(), anyString()))
                    .thenReturn(null);

            // need to tell mock to call the original, otherwise a default mocked stub will be called
            utilMoc.when(() -> Util.generateId(anyString()))
                    .thenCallRealMethod();

            assertEquals(sometext, Util.generateId(sometext));

        }
 类似资料:
  • 有什么方法可以模拟这个私有方法来测试我编写的方法吗?

  • 问题内容: 我是开发的新手,尤其是单元测试的新手。我想我的要求很简单,但是我很想知道其他人对此的想法。 假设我有两个这样的类- 假设我正在编写单元测试到测试方法。但是,假设我想像这样模拟课程。我正在使用Mockito来做到这一点。 我看到模拟未生效,并且断言失败。没有办法模拟我要测试的类的成员变量。? 问题答案: 您需要提供一种访问成员变量的方式,以便您可以进行模拟传递(最常见的方式是使用参数的s

  • 我正在使用JUnit4和mockito创建单元测试。我在尝试为一个类成员提供模拟实例时遇到了一个问题。 这是要测试的类: 当我尝试使用时,测试会产生一个。现在我尝试在测试类中注入缺失值: 我试图重新运行测试,但NPE仍然存在。 如何正确地做到这一点?

  • 问题内容: 我有一个建设者: 在模仿器中模拟生成器将使我对每种方法都无效。因此,有没有一种简单的方法可以使生成器在每次调用函数时返回自身,而无需使用来模拟每个函数本身。 问题答案: 您可以使用RETURN_DEEP_STUBS模拟链接API。 如果您知道将调用您的构建器的确切顺序,那么以下是如何使用它的示例: 不幸的是,这不会为您提供一种模拟“所有各种生成器方法”的通用方法,以使它们始终返回此值,

  • 问题内容: 我对模拟还很陌生,并且我一直在尝试模拟实际内容(本质上仅在内存中创建一个虚拟文件),以便在任何时候都不会将任何数据写入磁盘。 我尝试过模拟文件和模拟尽可能多的属性的解决方案,然后还使用文件写入器/缓冲写入器将其写入,但是这些方法不能很好地工作,因为它们需要规范路径。有人找到了除此以外的解决方案,但我正在解决这个错误? 我一直在这样做: 任何想法或指导都将非常有帮助。在此之后的某个地方,

  • 我尝试测试一个发送jms消息的类,但无法模拟JmsTemplate JmsProducer.class: JmsProducerTest。类别: 当我运行这个测试用例时,它给了我:java。lang.IllegalArgumentException:对象不是声明类的实例 你对这个问题有什么想法吗?