无法让 JUnit 测试失败(它应该)
Can't get JUnit test to fail (it should)
我在一个JUnit测试中有如下代码(只包含相关部分)
private String testRoot = System.getProperty("user.home");
private String destFail2 = testRoot + "/GoogleDrive/TestFail//..\...//*";
@Test
public void given_NamedParameterizedFileSet_when_SavedWithInvalidFileName_then_Exception() {
String invalidFullPathToFileSet = fsPathDir + invalidBackupName;
//test save fully parameterized empty file set at non-existent directory
try {
FileSet fs = new FileSet(backupName, dest);
try {
FileSet.save(invalidFullPathToFileSet, fs);
fail("Save name is invalid, should refuse save");
} catch (IOException e) {
assert(true);
}
} catch (Exception e1) {
e1.printStackTrace();
fail("Could not create the file set");
}
}
FileSet.save()的代码如下:
public static void save(String fullPathToFile, FileSet fileSet) throws IOException {
ObjectOutputStream out = null;
Path outFilePath = Paths.get(fullPathToFile);
Path outDirPath = outFilePath.getParent();
if (Files.exists(outFilePath)) {
Files.delete(outFilePath);
}
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}
try {
out = new ObjectOutputStream(new
BufferedOutputStream(Files.newOutputStream(outFilePath)));
out.writeObject(fileSet);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
}
上面的 FileSet.save() 方法应该失败,因为它被赋予我 认为 是一个无效的文件名,但不知何故代码运行得很好而没有抛出异常(在 Mac 上;还没有在 Windows 上尝试过)。
- 为什么代码是运行?
- 根据代码,我在哪里可以找到它创建的文件?
- 我需要什么样的文件名 "bad?" 我尝试创建一个带有冒号 (:) 的文件名,因为它应该是 Mac 上唯一的非法字符,但即使行得通,它最终创建了一个名称中间有冒号的文件...
- 是否有 "better" 方式来编写 FileSet.save()(而不是使用 Path,我应该使用 File 并将路径作为字符串传递给构造函数)?
异常处理不当,测试成功。在内部 try-catch
:
try {
FileSet.save(invalidFullPathToFileSet, fs);
fail("Save name is invalid, should refuse save");
} catch (IOException e) {
assert(true);
}
行 FileSet.save(invalidFullPathToFileSet, fs);
抛出异常,因此下一行本应未通过测试,但未执行,执行流程被重定向到 catch
块,您只需 assert(true)
(这是单元测试中完全无用的语句),然后退出内部和外部 try-catch
块,导致成功执行。
你应该做的是:
try {
FileSet.save(invalidFullPathToFileSet, fs);
} catch (IOException e) {
e.printStackTrace();
fail("Save name is invalid, should refuse save");
}
只要抛出异常,测试就会失败。
首先,不要使用 assert
关键字 - 如果您 运行 没有 -ea
参数的 java 应用程序 ("enable assertions"),此行将根本不执行。顺便说一句 assert true
什么都不做。
其次,你不关心的异常,那些你没有测试的,比如e1
不应该被捕获,声明测试方法抛出它。它将减少不必要的复杂性。
最后,我建议使用 ExpectedException
来做这个断言:
@Rule
public final ExpectedException expectedException = ExpectedException.none();
@Test
public void given_NamedParameterizedFileSet_when_SavedWithInvalidFileName_then_Exception() throws Exception {
String invalidFullPathToFileSet = fsPathDir + invalidBackupName;
FileSet fs = new FileSet(backupName, dest);
expectedException.expect(IOException.class);
FileSet.save(invalidFullPathToFileSet, fs);
}
这样您还可以查看消息。它还检查异常是否在 expect
行之后抛出。所以如果 new FileSet(...)
抛出 IOException,测试就会失败。注意,ExpectedException
需要注释为 @Rule
让 junit 现在在测试结束时执行检查。
我在一个JUnit测试中有如下代码(只包含相关部分)
private String testRoot = System.getProperty("user.home");
private String destFail2 = testRoot + "/GoogleDrive/TestFail//..\...//*";
@Test
public void given_NamedParameterizedFileSet_when_SavedWithInvalidFileName_then_Exception() {
String invalidFullPathToFileSet = fsPathDir + invalidBackupName;
//test save fully parameterized empty file set at non-existent directory
try {
FileSet fs = new FileSet(backupName, dest);
try {
FileSet.save(invalidFullPathToFileSet, fs);
fail("Save name is invalid, should refuse save");
} catch (IOException e) {
assert(true);
}
} catch (Exception e1) {
e1.printStackTrace();
fail("Could not create the file set");
}
}
FileSet.save()的代码如下:
public static void save(String fullPathToFile, FileSet fileSet) throws IOException {
ObjectOutputStream out = null;
Path outFilePath = Paths.get(fullPathToFile);
Path outDirPath = outFilePath.getParent();
if (Files.exists(outFilePath)) {
Files.delete(outFilePath);
}
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}
try {
out = new ObjectOutputStream(new
BufferedOutputStream(Files.newOutputStream(outFilePath)));
out.writeObject(fileSet);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
}
上面的 FileSet.save() 方法应该失败,因为它被赋予我 认为 是一个无效的文件名,但不知何故代码运行得很好而没有抛出异常(在 Mac 上;还没有在 Windows 上尝试过)。
- 为什么代码是运行?
- 根据代码,我在哪里可以找到它创建的文件?
- 我需要什么样的文件名 "bad?" 我尝试创建一个带有冒号 (:) 的文件名,因为它应该是 Mac 上唯一的非法字符,但即使行得通,它最终创建了一个名称中间有冒号的文件...
- 是否有 "better" 方式来编写 FileSet.save()(而不是使用 Path,我应该使用 File 并将路径作为字符串传递给构造函数)?
异常处理不当,测试成功。在内部 try-catch
:
try {
FileSet.save(invalidFullPathToFileSet, fs);
fail("Save name is invalid, should refuse save");
} catch (IOException e) {
assert(true);
}
行 FileSet.save(invalidFullPathToFileSet, fs);
抛出异常,因此下一行本应未通过测试,但未执行,执行流程被重定向到 catch
块,您只需 assert(true)
(这是单元测试中完全无用的语句),然后退出内部和外部 try-catch
块,导致成功执行。
你应该做的是:
try {
FileSet.save(invalidFullPathToFileSet, fs);
} catch (IOException e) {
e.printStackTrace();
fail("Save name is invalid, should refuse save");
}
只要抛出异常,测试就会失败。
首先,不要使用 assert
关键字 - 如果您 运行 没有 -ea
参数的 java 应用程序 ("enable assertions"),此行将根本不执行。顺便说一句 assert true
什么都不做。
其次,你不关心的异常,那些你没有测试的,比如e1
不应该被捕获,声明测试方法抛出它。它将减少不必要的复杂性。
最后,我建议使用 ExpectedException
来做这个断言:
@Rule
public final ExpectedException expectedException = ExpectedException.none();
@Test
public void given_NamedParameterizedFileSet_when_SavedWithInvalidFileName_then_Exception() throws Exception {
String invalidFullPathToFileSet = fsPathDir + invalidBackupName;
FileSet fs = new FileSet(backupName, dest);
expectedException.expect(IOException.class);
FileSet.save(invalidFullPathToFileSet, fs);
}
这样您还可以查看消息。它还检查异常是否在 expect
行之后抛出。所以如果 new FileSet(...)
抛出 IOException,测试就会失败。注意,ExpectedException
需要注释为 @Rule
让 junit 现在在测试结束时执行检查。