【问题标题】:Java - How to mock static block with MockitoJava - 如何使用 Mockito 模拟静态块
【发布时间】:2021-04-30 23:25:24
【问题描述】:

假设我有旧版 ElasticSearchIndexManager,即 Singletonestatic block,如下图所示,无法更改,我的目标是使用最新 Java JDK 支持的任何框架创建 Mock。

之前我们使用PowerMock 来完成这项工作,因为它能够创建mockStaticPartial,在启动时消除静态块作为 ElasticSearchIndexManager,如下面的代码所示。

PowerMock.mockStaticPartial(ElasticSearchIndexManager.class, "getInstance");
        EasyMock.expect(
                ElasticSearchIndexManager.getInstance(EasyMock.anyObject(AWSRegion.class)))
                .andReturn(null).anyTimes();

高版本JDK不支持PowerMock的问题。

现在我尝试使用 Mockito 3.7.7,它有所帮助,但没有解决我的问题,因为我们在旧代码静态块中。在 PowerMock 中,我们使用 mockStaticPartial 消除它。

POM.xml

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.7.7</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>3.7.7</version>
            <scope>test</scope>
        </dependency>

// New code - with 3.7.7 Mockito
    @Test
        public void testMockElasticSearchIndexManager() {
            AWSRegion region = mock(AWSRegion.class);
    
            try (MockedStatic<ElasticSearchIndexManager> theMock = Mockito.mockStatic(ElasticSearchIndexManager.class)) {
                theMock.when(() -> ElasticSearchIndexManager.getInstance(region)).thenReturn(null);
            }

        assertEquals(null, ElasticSearchIndexManager.getInstance(region));
    }

也许我错过了什么?我在断言org.mockito.exceptions.base.MockitoException: Cannot instrument class com.cloudally.index.ElasticSearchIndexManager because it or one of its supertypes could not be initialized 之前得到了异常@

,如果我删除 static block 它将起作用,如何以及是否有任何相同的能力来创建 Mockito 部分静态模拟, 或其他方式欢迎

非常感谢。

【问题讨论】:

  • 我见过类似的行为——你说得对,这里的静态块的内容很重要。您可以发布收到MockitoException 时获得的完整堆栈跟踪吗?就我而言,原因在完整的堆栈跟踪中突出显示,因为由于未在测试环境中初始化的未实例化的单例对象而引发了空指针异常。解决方案是为我的单例类添加另一个模拟。
  • 这是我的解决方法,我做了另一个静态块中的模拟。但我的问题是可能有像 PowerMock (mockStaticPartial) 中的内置模拟

标签: java unit-testing junit mocking mockito


【解决方案1】:

你可以试试吗?

try (MockedStatic<ElasticSearchIndexManager> theMock = Mockito.mockStatic(ElasticSearchIndexManager.class)) {
    theMock.when(() -> ElasticSearchIndexManager.getInstance(region)).thenReturn(null);
    assertEquals(null, ElasticSearchIndexManager.getInstance(region));
}

模拟上下文仅在 try-with-resource 块内有效。当它超出范围时,它会被关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2014-08-30
    • 2014-02-02
    相关资源
    最近更新 更多