【问题标题】:Powermock static final method in final class最终类中的Powermock静态最终方法
【发布时间】:2017-07-11 12:19:58
【问题描述】:

我正在编写的测试用例:

public class AClassUnderTest {

    // This test class has a method call
    public Long methodUnderTest() {

         // Uses the FinalUtilityClass which contains static final method
         FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>);

         // I want to mock above call so that test case for my "methodUnderTest" passes
    }
}

我还有最后一堂课。

public final class FinalUtilityClass {

   /**
    * Method has 3 parameters
    */
   public static final MyBean myStaticFinalMethod(<3-parameters-here>) {

   }
}

我已经在我的测试类中添加了以下代码:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ FinalUtilityClass.class })

我想写一个测试用例来模拟它。 我想模拟myStaticFinalMethod() 的调用,以便获得预期的MyBean instatnce,我可以在进一步的代码中使用它来通过我的测试用例。

&lt;3-parameters-here&gt; 是日历、字符串、字符串。

我试过了:

1)

PowerMockito.mock(FinalUtilityClass.class)
PowerMockito.when(FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>).thenReturn(new MyBean());

2)

PowerMockito.mockStatic(FinalUtilityClass.class)
PowerMockito.when(FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>).thenReturn(new MyBean());

3)

PowerMockito.spy(FinalUtilityClass.class)
PowerMockito.when(FinalUtilityClass.myStaticFinalMethod(<3-parameters-here>).thenReturn(new MyBean());

但对我没有任何帮助。请建议在final 类中模拟static final 方法的正确方法。

【问题讨论】:

  • 你在测试类中添加@RunWith(PowerMockRunner.class)作为类级别注解了吗?
  • 当然,我的其他案例运行良好。
  • PowerMockito 或 PowerMock ?
  • 它的PowerMockito
  • 好的,抱歉,那我已经提前回答了,我会删除我的答案。谢谢和抱歉。

标签: java unit-testing powermockito


【解决方案1】:

模拟对静态方法的调用需要以下steps:

  • 在测试用例的类级别使用@RunWith(PowerMockRunner.class) 注解。
  • 在测试用例的类级别使用@PrepareForTest(ClassThatContainsStaticMethod.class)注解
  • 使用PowerMock.mockStatic(ClassThatContainsStaticMethod.class)模拟该类的所有方法

当您按照文档中的这些步骤进行操作时,您的测试应该可以正常工作。由于 OP 似乎对 PowerMock 与 PowerMockito 感到困惑——这(或多或少)是同一件事:

PowerMock 和 PowerMockito 基于相同技术。他们只是有不同的“连接器”来与 EasyMock 或 Mockito 一起工作。所以,是的,上面的例子说PowerMock.mockStatic() - 但PowerMockito 也有mockStatic() 方法。从这个意义上说:核心 事物(例如关于带有注释的preparation)是相同的。例如,请参阅here(它们非常接近,以至于链接的教程说“PowerMock 简介” - 尽管它确实介绍了 PowerMockito。

你似乎不相信我 - 请看这个例子:

package ghostcat.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

final class ClassWithStatic {
    public final static int ignoreMethodCall(String a, String b, int c) {
        System.out.println("SHOULD NOT SHOW UP: " + a);
        return c;
    }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatic.class)
public class MockStaticTest {
    @Test
    public void test() {
        PowerMockito.mockStatic(ClassWithStatic.class);
        PowerMockito.when(ClassWithStatic.ignoreMethodCall("a", "b", 5)).thenReturn(42);
        org.junit.Assert.assertEquals(ClassWithStatic.ignoreMethodCall("a", "b", 5), 42);
    }
}

此测试通过;并且不打印任何东西。因此最终的静态方法会被模拟。

【讨论】:

  • 静态方法效果很好,但是静态最终呢?
  • 根据文档: > 请注意,即使类是最终类,您也可以在类中模拟静态方法。该方法也可以是final的
  • 根据 2) 点,我尝试使用 mockStatic,但它并没有模拟最终方法。它进入了我想模拟的方法。这适用于static 方法,这些方法不是最终的。
  • 这个答案使用PowerMock,问题中使用的是PowerMockito。
  • 我同意你的例子,如果 ClassWithStatic 是 final 怎么办?我的问题在于最后一堂课。
【解决方案2】:

我遇到了类似的问题,而且花了我很多时间。

我解决了,基于这个Mock system class with PowerMock documentation,当我意识到@PrepareForTest({ SomeClassToBePreparedForTesting.class })必须接收调用最终类中定义的静态方法的类,所以在你的情况下,为测试做准备,必须接收AClassUnderTest.class。

@RunWith(PowerMockRunner.class)
@PrepareForTest({ AClassUnderTest.class })

使用目标静态方法模拟最终类的正确方法是使用PowerMock.mockStatic(FinalClassThatDefinesStaticMethod.class),在您的情况下为FinalUtilityClass.class。

PowerMockito.mockStatic(FinalUtilityClass.class)
PowerMockito.when(FinalUtilityClass.method(params)).thenReturn(return);

此外,如果您有一些问题,例如:“无法模拟最终方法”,您可以创建文件 org/powermock/extensions/configuration.properties 并设置此配置 mockito.mock-maker-class=mock-maker-inline,就像 PowerMockito documentation 呈现的那样。

【讨论】:

    猜你喜欢
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多