Java 如何抑制和验证私有静态方法调用?

Java 如何抑制和验证私有静态方法调用?,java,junit,powermock,verify,suppress,Java,Junit,Powermock,Verify,Suppress,我目前在JUnit测试中遇到了障碍,需要一些帮助。所以我用静态方法得到了这个类,它将重构一些对象。为了简化起见,我举了一个小例子。这是我的工厂课程: class Factory { public static String factorObject() throws Exception { String s = "Hello Mary Lou"; checkString(s); return s; } private s

我目前在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。为什么会这样?

你可以这样做:

PowerMockito.doNothing().when(Factory.class,"checkString");
有关更多详细信息,请访问:

编辑:


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

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);      
    }
}

你好,我试过了,但发现了一个非法的argumentException。这真的很奇怪,整个设置中的一些东西很奇怪,尽管看起来很简单:(我现在这样尝试:mockStatic(Factory.class);Factory spy=spy(new Factory());PowerMockito.doNothing().when(Factory.class,“checkString”,Mockito.any(String.class));String s=spy.factorObject();
但是现在它为字符串s返回了一个值。我不明白…但是抑制似乎有效。当我抑制时(方法(Factory.class,“checkString”,String.class));不幸的是,我也得到了一个替代方法中声明的字符串。但至少私有方法被明显抑制。但为什么字符串突然为空?我想你是怎么把工具做得太过分了。不鼓励模仿被测类的想法。相反,你应该将值传递给被测方法将通过检查字符串验证并失败。这允许您在不依赖其实现的情况下完全测试被测方法。您正在设计的是脆弱的测试。我同意您的观点,但目前无法更改现有代码,因此验证必须更复杂一点。您是否提供类为了使这个答案更清晰,静态方法的使用是什么?具体来说是
mockStatic
suppress
方法和
验证私有
?为了测试的目的,我还使用了独立的包和所有依赖项:如果你使用Maven,你可能需要更少。这对我帮助很大。非常感谢你提供了详细的如何使它工作的utline。
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);      
    }
}