我正在尝试模拟一个创建局部变量的方法,尝试一些东西,并在抛出异常时进行记录。这是一段代码:
public void myFunction() {
//Some stuff
try {
new File("foo").getAbsoluteFile();
} catch (SecurityException e) {
//Do some logging
}
}
我想使用JMockit模拟这种日志记录行为(如果重要的话,使用1.8版)。所以我创建了以下测试:
@Test(expected=SecurityException.class)
public void testAbsoluteFile(
@Injectable final File file
) throws IOException {
new Expectations(File.class){{
new File(anyString);
result = file;
file.getAbsoluteFile();
result = new SecurityException();
}};
myFunction();
}
麻烦的是,这似乎给了NullPointerException
关于File.getAbsoluteFile()
的内部运作,我觉得这绝对是奇怪的:
java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NullPointerException>
Caused by: java.lang.NullPointerException
at java.io.Win32FileSystem.slashify(Win32FileSystem.java:56)
at java.io.Win32FileSystem.resolve(Win32FileSystem.java:330)
at java.io.File.getAbsolutePath(File.java:556)
at java.io.File.getAbsoluteFile(File.java:572)
at com.vue.rescoreservice.ExpectationTest.myFunction(ExpectationTest.java:39)
at com.vue.rescoreservice.ExpectationTest.testAbsoluteFile(ExpectationTest.java:33)
这似乎很奇怪,因为它说Win32FileSystem
类中的局部变量(不是典型Java API中的内部类)抛出NullPointerException,而以前从未发生过。
堆栈跟踪中的行如下:
//In myFunction()
new File("foo").getAbsoluteFile();
和
//In testAbsoluteFile()
myFunction();
为什么会这样?我怎样才能使JMockit不在内部类的局部变量上抛出NullPointerException?
答案 0 :(得分:3)
该问题已在最新的jMockit版本(1.14)中修复。如果您现在不想迁移,可以在1.8中修复测试(请参阅下面的代码)。
在这种情况下,不需要@Injectable。 File的构造函数被模拟为Expectations,并且需要模拟类本身而不是单个实例。在这种情况下,行为等同于@Mocked(但根据Expectations块中的调用,将部分模拟File)。
myFunction中的catch子句需要重新抛出SecurityException以允许测试通过。
@Test(expected=SecurityException.class)
public void testAbsoluteFile() throws IOException {
new Expectations(File.class) {{
File file = new File(anyString);
file.getAbsoluteFile();
result = new SecurityException();
}};
myFunction();
}
如果您希望将mock声明为参数,它也可以工作,但File不会被部分模拟(所有方法都将被模拟)。
@Test(expected=SecurityException.class)
public void testAbsoluteFile(@Mocked final File file) throws IOException {
new Expectations(){{
new File(anyString);
file.getAbsoluteFile();
result = new SecurityException();
}};
myFunction();
}
答案 1 :(得分:1)
@ Marc-André的最新消息。
在我使用JMockit 1.25的情况下,我不得不在期望之外定义文件变量,如下所示:
footerFirstColumn
在回答之前,可能是对JMockit的改变。