忽略调用内部静态调用
Ignoring invoking internal static call
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.when
和 PowerMockito.when
,存根在 运行 时间调试时不起作用。
由于您的评论表明无法更改生产代码,因此您 "simply" 必须深入研究 PowerMock 的静态模拟方面;例如概述 here。
基本上你需要为静态模拟启用IgnoreCall;然后你调用 ignoreMethodCall() 一个空操作。
但是正如你一直在问的那样:你问题的核心问题是你想模拟一个 static 方法,即 void.我在下面有一个完整的例子,但在此之前有一些解释。
重点是:你调用一个方法有两个原因:
- 有副作用
- 它 return 是一个值,也许也会产生副作用
void 方法只能 被调用以产生副作用。事情是:当你做 static 模拟时,它会在 class 级别上工作。
意思是:你指示 PowerMock "prevent" 某些 class 的静态方法中的任何一个从执行;您只是 "erase" 所有这些静态方法的副作用!因此,通过告诉 PowerMock 执行那些静态模拟,所有 void 方法都已经 "gone".
但如前所述,您也可以为其 return 值调用方法。然后是 Mockito 的 when()
方法启动的时候。您使用该方法来表示:当调用该 value-returning 方法时,然后做这个或那个。
长话短说;这是使用您要求的元素的 [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,并简单地将所有 JAR 从 powermock-mockito-junit-1.6.6.zip 导入我的测试项目。
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.when
和PowerMockito.when
,存根在 运行 时间调试时不起作用。
由于您的评论表明无法更改生产代码,因此您 "simply" 必须深入研究 PowerMock 的静态模拟方面;例如概述 here。
基本上你需要为静态模拟启用IgnoreCall;然后你调用 ignoreMethodCall() 一个空操作。
但是正如你一直在问的那样:你问题的核心问题是你想模拟一个 static 方法,即 void.我在下面有一个完整的例子,但在此之前有一些解释。
重点是:你调用一个方法有两个原因:
- 有副作用
- 它 return 是一个值,也许也会产生副作用
void 方法只能 被调用以产生副作用。事情是:当你做 static 模拟时,它会在 class 级别上工作。
意思是:你指示 PowerMock "prevent" 某些 class 的静态方法中的任何一个从执行;您只是 "erase" 所有这些静态方法的副作用!因此,通过告诉 PowerMock 执行那些静态模拟,所有 void 方法都已经 "gone".
但如前所述,您也可以为其 return 值调用方法。然后是 Mockito 的 when()
方法启动的时候。您使用该方法来表示:当调用该 value-returning 方法时,然后做这个或那个。
长话短说;这是使用您要求的元素的 [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,并简单地将所有 JAR 从 powermock-mockito-junit-1.6.6.zip 导入我的测试项目。