Unit testing 使用JMockit进行模拟会对内部类的局部变量抛出NullPointerException
我试图模拟一个方法,该方法创建一个局部变量,尝试一些东西,并在抛出异常时进行日志记录。下面是一段代码:Unit testing 使用JMockit进行模拟会对内部类的局部变量抛出NullPointerException,unit-testing,nullpointerexception,jmockit,Unit Testing,Nullpointerexception,Jmockit,我试图模拟一个方法,该方法创建一个局部变量,尝试一些东西,并在抛出异常时进行日志记录。下面是一段代码: public void myFunction() { //Some stuff try { new File("foo").getAbsoluteFile(); } catch (SecurityException e) { //Do some logging } } 我想使用JMockit模拟这种日志记录行为(如果有必要,可以
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)
及
为什么会这样?我如何使JMockit不会在内部类的局部变量上抛出NullPointerException?这个问题在最新的JMockit版本(1.14)中得到了修复。如果您现在不想迁移,可以在1.8中修复测试(请参阅下面的代码) 在这种情况下,不需要@Injectable。文件的构造函数根据预期进行模拟,这需要模拟类本身,而不是单个实例。在这种情况下,行为相当于@Mocked(但文件将根据Expectations块中的调用进行部分模拟) 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声明为参数,它也可以工作,但不会对文件进行部分mock(所有方法都将被mock)
该问题已在最新的jMockit版本(1.14)中修复。如果您现在不想迁移,可以在1.8中修复测试(请参阅下面的代码) 在这种情况下,不需要@Injectable。文件的构造函数根据预期进行模拟,这需要模拟类本身,而不是单个实例。在这种情况下,行为相当于@Mocked(但文件将根据Expectations块中的调用进行部分模拟) 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声明为参数,它也可以工作,但不会对文件进行部分mock(所有方法都将被mock)
更新@Marc Andréanswer 在我使用JMockit 1.25的情况下,我必须在预期之外定义文件变量,如下所示:
@Test(预期=SecurityException.class)
public void TestAbsolutionFile()引发IOException{
文件文件=新文件(“”);
新期望(File.class){{
getAbsoluteFile();
结果=新的SecurityException();
}};
myFunction();
}
也许这是JMockit在回答之前的一个变化。关于@Marc Andréanswer的更新 在我使用JMockit 1.25的情况下,我必须在预期之外定义文件变量,如下所示:
@Test(预期=SecurityException.class)
public void TestAbsolutionFile()引发IOException{
文件文件=新文件(“”);
新期望(File.class){{
getAbsoluteFile();
结果=新的SecurityException();
}};
myFunction();
}
可能是在回答之前JMockit的一个变化。您能提供进一步的信息吗?错误日志指向ExpectationTest.java中代码的两个区域,第59行和第65行。这些是什么行?@user3334871我已经把它添加到问题中了。你能提供进一步的信息吗?错误日志指向ExpectationTest.java中代码的两个区域,第59行和第65行。这些行是什么?@user3334871我已将其添加到问题中。在java.io.Win32FileSystem中测试失败的原因是没有正确模拟文件类,并且使用anyString作为参数调用了真正的实现。anyString的值为null,因此它会因NullPointerException而失败。回答得很好!只是吹毛求疵:最好在这里部分模拟
文件
以获得特定的文件名=>新期望(File.class){{{new File(“foo”).getAbsoluteFile();result=new SecurityException();}代码>在java.io.Win32FileSystem中测试失败的原因是没有正确模拟文件类,并且使用anyString作为参数调用实际实现。anyString的值为null,因此它会因NullPointerException而失败。回答得很好!只是吹毛求疵:最好在这里部分模拟文件
以获得特定的文件名=>新期望(File.class){{{new File(“foo”).getAbsoluteFile();result=new 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();
}
@Test(expected=SecurityException.class)
public void testAbsoluteFile(@Mocked final File file) throws IOException {
new Expectations(){{
new File(anyString);
file.getAbsoluteFile();
result = new SecurityException();
}};
myFunction();
}