最终类中的Powermock静态最终方法

时间:2017-07-11 12:19:58

标签: java unit-testing powermockito

我写的测试案例:

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,我可以在其他代码中使用它来传递我的测试用例。

<3-parameters-here>是Calendar,String,String。

我尝试过

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());

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

2 个答案:

答案 0 :(得分:7)

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

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

当您按照文档记录这些步骤时,您的测试应该可行。由于OP似乎对PowerMock与PowerMockito相混淆 - 这或多或少都是同样的事情:

PowerMock和PowerMockito基于相同技术。他们只是有不同的连接器&#34;与EasyMock或Mockito合作。所以,是的,上面的示例说明PowerMock.mockStatic() - 但PowerMockito也有mockStatic()个方法。从这个意义上说:核心事物(例如关于带注释的准备)是相同的。例如,请参阅here(它们非常接近,链接的教程说&#34; PowerMock简介&#34; - 虽然它确实引入了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);
    }
}

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

答案 1 :(得分:0)

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

我解决了,基于这个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 呈现的那样.