3

我有两行代码:

File file = new File("report_はな.html");
Path path = Paths.get(file.getCanonicalPath());

无论如何我可以模拟静态方法:

Paths.get(file.getCanonicalPath());

并且只抛出异常 InvalidPathException?

我尝试了powermockito,但它似乎不起作用

PowerMockito.mockStatic(Paths.class);
PowerMockito.doReturn(null).doThrow(new InvalidPathException("","")).when(Paths.class);

整个想法是我试图重现在英文Mac下,Mac默认编码设置为US-ASCII的错误,其中Path path = Paths.get("report_はな.html"); 将抛出此 InvalidPathException。

4

1 回答 1

3

如此所述,您必须跳过一些障碍来模拟“系统”类,即由系统类加载器加载的类。

具体来说,虽然在普通 PowerMock 测试中,@PrepareForTest()注解标识了您要模拟其静态方法的类,但在“系统”PowerMock 测试中,注解需要标识调用静态方法的类(通常是被测类)。

例如,假设我们有以下类:

public class Foo {
    public static Path doGet(File f) throws IOException {
        try {
            return Paths.get(f.getCanonicalPath());
        } catch (InvalidPathException e) {
            return null;
        }
    }
}

我们想测试这个类是否真的返回nullif Paths.get()throws an InvalidPathException。为了测试这一点,我们写:

@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();
    }
}

注意:我写了Paths.get(any(String.class)),但如果需要,你可以模拟一些更具体的东西,例如Paths.get("foo"))or Paths.get(new File("report_はな.html").getCanonicalPath())

于 2016-03-21T00:29:05.663 回答