I have a static method that is mocked using PowerMock to throw an exception. (It deletes files.) Unfortunately, during my @After
(after-each-test) method, I need to call this method without the mocks. How can I umock a method?
I don't see an equivalent to Mockito.reset()
. [ Ref: mockito : how to unmock a method? ]
Example:
@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();
}
}
verifyStatic(VerificationModeFactory. times(2)) which tells PowerMock to verify static method was called 2 times. The second part is Utils. randomDistance(1) which tells exactly which static method should be verified.
Try moving your static mock setup to an @BeforeClass setup method, but leave your reset(mocks) call in your test setup() method. You want to setup your mockStatic only once, but because they're static, you will want to reset them for every test or they'll muddle with subsequent tests.
PowerMockito is a PowerMock's extension API to support Mockito. It provides capabilities to work with the Java Reflection API in a simple way to overcome the problems of Mockito, such as the lack of ability to mock final, static or private methods.
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With