I have two line of code:
File file = new File("report_はな.html");
Path path = Paths.get(file.getCanonicalPath());
Is there anyway that I can mock the static method:
Paths.get(file.getCanonicalPath());
And only throw the exception InvalidPathException?
I tried the powermockito, but it seems does not working
PowerMockito.mockStatic(Paths.class);
PowerMockito.doReturn(null).doThrow(new InvalidPathException("","")).when(Paths.class);
The whole idea is I am trying to reproduce the bug that Under the English Mac, the Mac default encoding setting is US-ASCII, which Path path = Paths.get("report_はな.html"); will throw this InvalidPathException.
As documented here, you have to jump through some hoops to mock "system" classes, i.e. classes loaded by the system classloader.
Specifically, whereas in a normal PowerMock test the @PrepareForTest()
annotation identifies the class whose static methods you want to mock, in a "system" PowerMock test the annotation needs to identify the class that calls the static methods (usually the class under test).
For instance, say we have the following class:
public class Foo {
public static Path doGet(File f) throws IOException {
try {
return Paths.get(f.getCanonicalPath());
} catch (InvalidPathException e) {
return null;
}
}
}
We want to test that this class does in fact return null
if Paths.get()
throws an InvalidPathException
. To test this, we write:
@RunWith(PowerMockRunner.class) // <- important!
@PrepareForTest(Foo.class) // <- note: Foo.class, NOT Paths.class
public class FooTest {
@Test
public void doGetReturnsNullForInvalidPathException() throws IOException {
// Enable static mocking on Paths
PowerMockito.mockStatic(Paths.class);
// Make Paths.get() throw IPE for all arguments
Mockito.when(Paths.get(any(String.class)))
.thenThrow(new InvalidPathException("", ""));
// Assert that method invoking Paths.get() returns null
assertThat(Foo.doGet(new File("foo"))).isNull();
}
}
Note: I wrote Paths.get(any(String.class))
but you could mock something more
specific if need be, e.g. Paths.get("foo"))
or Paths.get(new File("report_はな.html").getCanonicalPath())
.