如何撤消/重置 PowerMockito.mockStatic?

Kar*_*ter 5 java static mocking powermock powermockito

假设我有以下课程

public class StaticClass {

    public static void staticMethod() throws SomeException {
        System.out.println("staticMethod");
    }

    private StaticClass() {
    }
}
Run Code Online (Sandbox Code Playgroud)

public class SomeClass {

    public void someMethod() {
        try {
            StaticClass.staticMethod();
        }catch(SomeException ex) {
            System.out.println("SomeException occurred");
            return;
        }
        System.out.println("SomeException didn't occur");
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在测试

@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticClass.class)
public class SomeClassTest {

    @Test
    public void testStaticMethod() throws Exception {
        mockStatic(StaticClass.class);
        doThrow(new SomeException("unimportant message")).when(StaticClass.class,
                "staticMethod");
        //test something where exception is needed
        SomeClass instance = new SomeClass();
        try {
            instance.someMethod();
            fail("IllegalStateException expected");
        }catch(IllegalStateException expected) {
        }
        //now test something where exception isn't needed
        instance.someMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

如何撤消静态模拟/抛出的配置,SomeException以便我可以在第二个 try-catch 块之后测试代码instance.someMethod()

PowerMock:如何取消模拟方法?不适用,因为没有模拟引用传递 toMockito.reset和传递StaticClassCause java.lang.ClassCastException: java.lang.Class cannot be cast to org.mockito.internal.creation.bytebuddy.MockAccess

SomeException只是简单地延伸Exception

https://gitlab.com/krichter/powermock-undo-statik-mocking提供了 SSCCE 。

我正在使用 PowerMock 1.7.3。

And*_*w S 3

我认为,但一般来说,单元测试应该使用单个代码路径。(我认为这是对测试方法应用单一责任。)

但是我关于拆分测试的建议确实解决了问题。我不知道细节,但 @PrepareForTest为每个 test提供了一个新的 StaticClass 。

这些单独的测试有效:

@Test
public void testStaticMethodWhenSomethingUnexpectedHappens() throws Exception {
    mockStatic(StaticClass.class);
    // changed exception type
    doThrow(new IllegalStateException("unimportant message")).when(StaticClass.class, "staticMethod");

    SomeClass instance = new SomeClass();
    try {
        instance.someMethod();
        fail("IllegalStateException expected");
    } catch (IllegalStateException expected) {
    }

    // added verification
    verifyStaticMethodWasInvokedOneTime();
}

@Test
public void testStaticMethodHappyPath() throws Exception {
    mockStatic(StaticClass.class);
    doNothing().when(StaticClass.class, "staticMethod");

    SomeClass instance = new SomeClass();
    instance.someMethod();

    // added verification
    verifyStaticMethodWasInvokedOneTime();
}

private void verifyStaticMethodWasInvokedOneTime() throws SomeException {
    verifyStatic(StaticClass.class);
    StaticClass.staticMethod();
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的方法,可以简化将来的并行化。不过,https://github.com/powermock/powermock/issues/787 中讨论了否则执行的功能。 (2认同)