【问题标题】:How to suppress and verify private static method calls?如何抑制和验证私有静态方法调用?
【发布时间】:2013-05-03 18:20:11
【问题描述】:

我目前在 JUnit 测试中遇到困难,需要一些帮助。所以我得到了这个带有静态方法的类,它将重构一些对象。为了简单起见,我做了一个小例子。这是我的工厂课程:

class Factory {

    public static String factorObject() throws Exception {
        String s = "Hello Mary Lou";
        checkString(s);
        return s;
    }

    private static void checkString(String s) throws Exception {
        throw new Exception();
    }
}

这是我的测试课:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Factory.class })        
public class Tests extends TestCase {

    public void testFactory() throws Exception {

        mockStatic(Factory.class);
        suppress(method(Factory.class, "checkString"));
        String s = Factory.factorObject();
        assertEquals("Hello Mary Lou", s);
    }
}

基本上我试图实现的是私有方法checkString()应该被抑制(所以不会抛出异常),并且还需要验证方法checkString()实际上是在方法factorObject()中调用的。

更新: 抑制使用以下代码正常工作:

suppress(method(Factory.class, "checkString", String.class));
String s = Factory.factorObject();

...但是它为字符串“s”返回NULL。这是为什么呢?

【问题讨论】:

  • 恕我直言,您使用该工具太过分了。不鼓励嘲笑被测类的想法。相反,您应该将值传递给您的测试方法,该方法将通过检查字符串通过和失败验证。这使您可以完全测试被测方法,而无需依赖其实现。你设计的是脆弱的测试。
  • 我同意你的看法,但目前无法更改现有代码,因此验证必须稍微复杂一些。

标签: java junit powermock verify suppress


【解决方案1】:

好的,我终于找到了所有问题的解决方案。如果有人偶然发现类似问题,代码如下:

import junit.framework.TestCase;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.times;
import static org.powermock.api.support.membermodification.MemberModifier.suppress;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Factory.class)
public class Tests extends TestCase {

    public void testFactory() throws Exception {

        mockStatic(Factory.class, Mockito.CALLS_REAL_METHODS);
        suppress(method(Factory.class, "checkString", String.class));
        String s = Factory.factorObject();
        verifyPrivate(Factory.class, times(1)).invoke("checkString", anyString()); 
        assertEquals("Hello Mary Lou", s);      
    }
}

【讨论】:

  • 您能提供静态方法的类以使这个答案更清楚吗?具体是mockStaticsuppressmethodverifyPrivate?
  • 出于测试目的,我还使用了具有所有依赖项的独立包:code.google.com/p/powermock/downloads/… 如果您使用 Maven,您可能需要的更少。
  • 这对我帮助很大。非常感谢您提供有关如何使其工作的详细代码大纲。
【解决方案2】:

你可以这样做:

PowerMockito.doNothing().when(Factory.class,"checkString");

更多详情您可以访问:
http://powermock.googlecode.com/svn/docs/powermock-1.3.7/apidocs/org/powermock/api/mockito/PowerMockito.html

编辑:

ClassToTest spy = spy(new ClassToTest ());
doNothing().when(spy).methodToSkip();
spy.methodToTest();

【讨论】:

  • 您好,我试过了,但得到了 IllegalArgumentException。这真的很奇怪,整个设置中的某些东西很奇怪,虽然它看起来很简单:(
  • 我现在这样试了:mockStatic(Factory.class);工厂间谍 = 间谍(新工厂()); PowerMockito.doNothing().when(Factory.class,"checkString", Mockito.any(String.class));字符串 s = spy.factorObject();
    但现在它为我返回了 String 的 。我不明白...
  • 抑制似乎有效。当我做suppress(method(Factory.class, "checkString", String.class));不幸的是,我也得到了一个 而不是方法中声明的字符串。但至少私有 Method 显然被压制了。但是为什么字符串突然为空?
猜你喜欢
  • 2019-07-26
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 2017-10-08
  • 2013-01-01
  • 2017-01-13
  • 2019-03-27
  • 1970-01-01
相关资源
最近更新 更多