2016-12-07 125 views
4
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尝试,在运行时调试时,stubbing不起作用。
+2

事情是:** static **是OO设计中的一个异常;正如你刚刚注意到的那样:它使你的代码更难以测试。 PowerMock可以“解决”这个问题;但我宁愿推荐您更改您的生产代码。没有静态调用,没有这样的问题。 – GhostCat

+0

如果重构很容易,那么到那时我就完成了。不幸的是,由于手头上的OO设计不佳,我陷入了困境。你提到'PowerMock可以解决这个问题',关心分享如何? –

+0

你会惊讶我多久会得到答案,建议修复破碎的设计,而不是使用PowerMock。无论如何,你现在得到了答案。 – GhostCat

回答

5

由于您的意见表明,更改您的生产代码是不可能的,您只需“深入”PowerMock的静态模拟方面;如例如所概述的here

基本上你需要启用IgnoreCall进行静态模拟;然后您拨打电话ignoreMethodCall() a no-op。

但是当你继续问:核心问题,你的问题是要模拟出一个静态方法是无效的事实。我在下面有一个完整的例子,但在此之前有一些解释。

的一点是:你调用一个方法有两个原因:

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

A void方法可以只有被称为副作用。而事情是:当你做静态嘲笑,那么级别的作品。

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

但正如所说的,你也可以调用方法来获得它们的返回值。然后是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导入到我的测试项目中。

+0

无法理解为什么存根参数不起作用?使用'Mockito.when'和'PowerMockito.when',两者都没有相应的工作。 –

+0

这应该是被接受的答案。你读过@GhostCat的链接吗? 'PowerMockito.mockStatic(IgnoreCall.class);'并确保你正在使用PowerMocks跑步者。 –

+0

@CyrilHorad我也有点赞同大卫说的话。你看,你打算做的事情是*记录在我连接的答案中。你在那里失去了什么?你真的需要人们为你特别写一个例子吗? – GhostCat