忽略调用内部静态调用

Kai*_*ugo 4 junit mockito powermock powermockito

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

    // return
}
Run Code Online (Sandbox Code Playgroud)

使用上面的代码片段,是否可以测试忽略调用的方法而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
    }

}
Run Code Online (Sandbox Code Playgroud)

笔记:

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

Gho*_*ica 6

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

基本上你需要启用IgnoreCall进行静态模拟; 然后你调用ignoreMethodCall()一个no-op.

但是你一直在问:你的问题的核心问题是你想要模拟一个无效静态方法.我在下面有一个完整的例子,但在此之前有一些解释.

关键是:您调用方法有两个原因:

  1. 它有副作用
  2. 它返回一个值,也可能导致副作用

空隙方法可以被调用的副作用.事情是:当你做静态模拟时,那就是在级别上工作.

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

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

长话短说; 这是使用您要求的元素的[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");
  }
}
Run Code Online (Sandbox Code Playgroud)

如你的例子......有IgnoreCall; 在那个我称之为"call"的静态方法中使用.

这打印:

statement1
statement2
Run Code Online (Sandbox Code Playgroud)

当我进去评论出来

//      PowerMockito.mockStatic(IgnoreCall.class);
Run Code Online (Sandbox Code Playgroud)

它打印:

statement1
SHOULD NOT SHOW UP: yeha
statement2
Run Code Online (Sandbox Code Playgroud)

因此,一个简单的例子,应该告诉你,正是你需要做什么.

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