为什么 file.exists() 检查在 mockito 参数匹配器中的 file.delete() 之后执行?
Why is the file.exists() check executed after the file.delete() in mockito argument matcher?
在我的代码中,我尝试测试一个文件,该文件的路径以字符串形式提供给如下方法:
TestClass testClass = spy(new TestClass());
@Test
public void test() {
testClass.someMethod();
doNothing().when(testClass).someOtherMethod(any(String.class));
Mockito.verify(testClass, times(1)).someOtherMethod(argThat(this::checkFile));
}
private boolean checkFile(final String filePath) {
boolean fileLegit = true;
File file = new File(filePath);
assertThat(file).exists();
try {
// Some testing on the file
} catch (IOException | IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
fileLegit = false;
}
file.delete(); // <- Trying to delete
return fileLegit;
}
这里我得到以下异常:
java.lang.AssertionError:
Expecting file:
<path\to\file>
to exist
当我删除 file.delete()
时,一切正常,但文件没有被删除(很明显)。不过我需要在测试后删除它,所以你知道为什么会发生这种情况以及如何解决它吗?
这里是 TestClass 对象,因为有些人对它很感兴趣(盲码,但你明白了):
public class TestClass {
public void someMethod() {
List<String> content = new ArrayList<>();
content.add("test");
Path path = Paths.get(/* Choose a path */);
if (!Files.exists(path)) {
Files.createFile(path);
}
Files.write(path, content, StandardCharsets.UTF_8);
someOtherMethod(path.toString());
}
void someOtherMethod(String filepath) {
System.out.println(filepath);
}
}
我假设 testClass
是您的 TestClass
对象上的 spy
,即使您的示例没有提及这一点。请注意,如果可以,您应该尽量将 spies
的使用限制在遗留代码中。
您的问题与 运行 单元测试时 checkFile
方法被调用两次有关。您编写此代码的前提是您的方法仅被调用一次,但在这种情况下 Mockito
并非如此。
您可以通过在您的方法中添加 breakpoint
或 System.out
来轻松验证。
要解决此问题,请将文件删除逻辑与匹配器分开。您可能想要添加一个清理 (@AfterEach
) 方法。
在我的代码中,我尝试测试一个文件,该文件的路径以字符串形式提供给如下方法:
TestClass testClass = spy(new TestClass());
@Test
public void test() {
testClass.someMethod();
doNothing().when(testClass).someOtherMethod(any(String.class));
Mockito.verify(testClass, times(1)).someOtherMethod(argThat(this::checkFile));
}
private boolean checkFile(final String filePath) {
boolean fileLegit = true;
File file = new File(filePath);
assertThat(file).exists();
try {
// Some testing on the file
} catch (IOException | IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
fileLegit = false;
}
file.delete(); // <- Trying to delete
return fileLegit;
}
这里我得到以下异常:
java.lang.AssertionError:
Expecting file:
<path\to\file>
to exist
当我删除 file.delete()
时,一切正常,但文件没有被删除(很明显)。不过我需要在测试后删除它,所以你知道为什么会发生这种情况以及如何解决它吗?
这里是 TestClass 对象,因为有些人对它很感兴趣(盲码,但你明白了):
public class TestClass {
public void someMethod() {
List<String> content = new ArrayList<>();
content.add("test");
Path path = Paths.get(/* Choose a path */);
if (!Files.exists(path)) {
Files.createFile(path);
}
Files.write(path, content, StandardCharsets.UTF_8);
someOtherMethod(path.toString());
}
void someOtherMethod(String filepath) {
System.out.println(filepath);
}
}
我假设 testClass
是您的 TestClass
对象上的 spy
,即使您的示例没有提及这一点。请注意,如果可以,您应该尽量将 spies
的使用限制在遗留代码中。
您的问题与 运行 单元测试时 checkFile
方法被调用两次有关。您编写此代码的前提是您的方法仅被调用一次,但在这种情况下 Mockito
并非如此。
您可以通过在您的方法中添加 breakpoint
或 System.out
来轻松验证。
要解决此问题,请将文件删除逻辑与匹配器分开。您可能想要添加一个清理 (@AfterEach
) 方法。