PowerMock: How to unmock a method?

二次信任 提交于 2019-12-03 23:51:55

This took me a while to figure out, so I am answering my own question.

AFAIK, you need to "undo" each mock. Mockito.reset() will not work with Class<?> references. At the end of the test method, add:

// Undo the mock above because we need to call PathUtils.removeFile() within @After.
PowerMockito.doCallRealMethod().when(PathUtils.class);
PathUtils.removeFile(Mockito.any(File.class));

The only way you can undo mocking of a static method with PowerMock is when you mock a class at the beginning of a test and then undo the mock at the end of a test. It doesn't matter if you use SPY or a regular mocking.

Tested with:

"org.powermock" % "powermock" % "1.5" % Test,
"org.powermock" % "powermock-api-mockito" % "1.6.1" % Test,

Test class

package mytests;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.fest.assertions.Assertions.assertThat;


@RunWith(PowerMockRunner.class)
@PrepareForTest({StaticTest.class})
public class TestTest {

    @Before
    public void checkIfOriginalMethodGetsCalled() {

//        PowerMockito.mockStatic(StaticTest.class); if you do this in @Before you are not going to be able to undo it
        assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
        assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
    }

    @Test
    public void test1() {
        assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
    }

    @Test
    public void test3_mocking() {
        mock(); // mock or spy static methods in a test, not in @Before 

        Mockito.when(StaticTest.staticMethod()).thenReturn("MOCKED VALUE");
        assertThat(StaticTest.staticMethod()).isEqualTo("MOCKED VALUE");
        assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");

        undoMock(); // undo the mock at the end of each test, not in @After
    }

    private void mock() {
//        PowerMockito.mockStatic(StaticTest.class); both, spy and mockStatic work ok
        PowerMockito.spy(StaticTest.class);
    }

    private void undoMock() {
        PowerMockito.doCallRealMethod().when(StaticTest.class);
        assertThat(StaticTest.staticMethod()).isNull(); // the undo is going to work in the next test, not here yet. 
    }

    @Test
    public void test2() {
        assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
    }

    @After
    public void checkIfOriginalMethodGetsCalled_AfterMockUndo() {

        // undoMock(); in @After  doesn't work with static methods
        assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
        assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
    }
}

class StaticTest {
    public static String staticMethod() {
        return "ORIGINAL VALUE";
    }

    public static String otherStaticMethod() {
        return "SPY TEST ORIGINAL";
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!