忽略调用内部静态调用

时间:2016-12-07 09:39:50

标签: junit mockito powermock powermockito

public static ResponseBean call(Bean bean) throws Exception {
    // statements...
    IgnoreCall.ignoreMethodCall(bean);
    // statements...

    // return
}

使用上面的代码片段,是否可以测试忽略IgnoreCall.ignoreMethod(Bean)调用的方法而无需将整个语句置于布尔条件下?

这是单元测试代码段:

@RunWith(PowerMockRunner.class)
@PrepareTest
public ClassHelperTest {

    @Test
    public void testCall() throws Excpetion {
        // stubbing...
        ResponseBean responseBean = ClassHelper.call(bean);
        // verify/ies
        // assert/s
    }

}

注意:

  • 应避免重构ClassHelper.call(Bean)。即使是糟糕的OO设计,重构也是昂贵的。
  • 方法签名被锁定,除非另一种模式适用于替换。
  • 在目标静态方法上使用Mockito.whenPowerMockito.when进行了尝试,存根不适用于运行时调试。

1 个答案:

答案 0 :(得分:6)

由于您的评论表明无法更改您的生产代码,因此您“只需”深入了解PowerMock的静态模拟方面;例如概述here

基本上你需要启用 IgnoreCall 进行静态模拟;然后你调用 ignoreMethodCall()一个无操作。

但是你一直在问:你的问题的核心问题是你想要嘲笑一个静态方法 void 。我在下面有一个完整的例子,但在此之前有一些解释。

关键是:你打电话给一个方法有两个原因:

  1. 有副作用
  2. 它返回一个值,也可能导致副作用
  3. void 方法可以调用副作用。事情是:当你进行静态模拟时,那就适用于级别。

    含义:指示PowerMock“阻止”某些类的任何静态方法执行;你只需“擦除”所有那些静态方法的副作用!因此,通过告诉PowerMock进行那些静态模拟,所有的void方法都已经“消失”了。

    但如上所述,您也可以为其返回值调用方法。然后就是Mockito的when()方法开始的时候。你使用那个方法说:当调用返回值的方法时,那么就这样做。

    长话短说;这是使用您要求的元素的[mcve]:

    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;
    
    class IgnoreCall {
      public static void ignoreMethodCall(Object o) {
        System.out.println("SHOULD NOT SHOW UP: " + o);
      }
    }
    
    class CuT {
      public static Object call(Object bean) {
        System.out.println("statement1");
        IgnoreCall.ignoreMethodCall(bean);
        System.out.println("statement2");
        return "whatever";
      }
    }
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(IgnoreCall.class)
    public class PMTest {
      @Test
      public void test() {
        PowerMockito.mockStatic(IgnoreCall.class);
        CuT.call("yeha");
      }
    }
    

    在你的例子中......有IgnoreCall;在我称之为“call”的静态方法中使用。

    打印:

    statement1
    statement2
    

    当我进去评论时

    //      PowerMockito.mockStatic(IgnoreCall.class);
    

    打印:

    statement1
    SHOULD NOT SHOW UP: yeha
    statement2
    

    所以,一个简单的例子应该告诉你完全你需要做什么。

    我使用eclipse neon,IBM java8 JDK,只需将powermock-mockito-junit-1.6.6.zip中的所有JAR导入我的测试项目。