PowerMock:如何取消模拟方法?

我有一个静态方法,使用PowerMock模拟抛出exception。 (它删除文件。)不幸的是,在我的@After (每次测试后)方法中,我需要在没有模拟的情况下调用此方法。 我该如何摆弄方法?

我没有看到Mockito.reset()的等价物。 [参考: mockito:如何取消模拟方法? ]

例:

 @RunWith(PowerMockRunner.class) @PrepareForTest(PathUtils.class) // Important: This class has a static method we want to mock. public class CleaningServiceImplTest2 extends TestBase { public static final File testDirPath = new File(CleaningServiceImplTest2.class.getSimpleName()); @BeforeClass public static void beforeAllTests() throws PathException { recursiveDeleteDirectory(testDirPath); } @AfterClass public static void afterAllTests() throws PathException { recursiveDeleteDirectory(testDirPath); } private File randomParentDirPath; private CleaningServiceImpl classUnderTest; @Before public void beforeEachTest() { randomParentDirPath = new File(testDirPath, UUID.randomUUID().toString()).getAbsoluteFile(); classUnderTest = new CleaningServiceImpl(randomParentDirPath); } @After public void afterEachTest() throws PathException { recursiveDeleteDirectory(randomParentDirPath); } public static void recursiveDeleteDirectory(File dirPath) throws PathException { // calls PathUtils.removeFile(...) } @Test public void run_FailWhenCannotRemoveFile() throws IOException { // We only want to mock one method. Use spy() and not mockStatic(). PowerMockito.spy(PathUtils.class); // These two statements are tightly bound. PowerMockito.doThrow(new PathException(PathException.PathExceptionReason.UNKNOWN, randomParentDirPath, null, "message")) .when(PathUtils.class); PathUtils.removeFile(Mockito.any(File.class)); classUnderTest.run(); } } 

我花了一段时间才弄明白,所以我回答了自己的问题。

AFAIK,你需要“撤消”每个模拟。 Mockito.reset()不适用于Class引用。 在测试方法结束时,添加:

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

使用PowerMock撤消静态方法模拟的唯一方法是在测试开始时模拟一个类,然后在测试结束时撤消模拟。 如果您使用SPY或常规模拟无关紧要。

经测试:

 "org.powermock" % "powermock" % "1.5" % Test, "org.powermock" % "powermock-api-mockito" % "1.6.1" % 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"; } }