无法让JUnit测试失败(应该)

时间:2015-11-09 12:27:37

标签: java file junit save

我在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上尝试过。)

  1. 为什么代码在运行?
  2. 鉴于代码,我在哪里查找它创建的文件?
  3. 我需要什么样的文件名“糟糕?”我尝试在其中创建一个冒号(:),因为它应该是Mac上唯一的非法字符,但即使这样也可行,最终会在名称中间创建一个带冒号的文件...
  4. 是否有一种“更好”的方式来编写FileSet.save()(而不是使用Path,我应该使用File并将路径作为字符串传递给构造函数)?

2 个答案:

答案 0 :(得分:2)

首先,不要使用assert关键字 - 如果运行没有-ea参数的java应用程序(“启用断言”),则该行根本不会执行。顺便说一下,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现在在测试结束时执行检查。

答案 1 :(得分:0)

由于异常处理不当,测试成功。在内部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块,你只需{{1} (在单元测试中这是一个完全无用的语句)然后退出内部和外部assert(true)块,导致成功执行。

你应该做的是:

try-catch

每当抛出异常时,这将无法通过测试。