Java:如何对在方法范围内创建和操作文件的方法进行单元测试?

时间:2015-02-19 17:14:34

标签: java unit-testing junit jmockit

我正在使用JUnit和JMockit创建一个单元测试方法来测试CSV文件的创建和操作。如何拦截正在创建的文件以确保正确创建?

@Test
public void testPersistResultsAsCSV() throws IOException {
    final Long id = new Long(1234l);

    TableRow row = new TableRow();
    row.setValue(317l);
    row.setId(1234l);

    final List<TableRow> rows = new ArrayList<TableRow>();
    rows.add(row);

    final List<TableRow> empty = new ArrayList<TableRow>();

    new Expectations() {
        {
            tableService.findTableRowsById(id, (TableQueryOptions)any);
            result = rows;

            tableService.findTableRowsById(id, (TableQueryOptions)any);
            result = empty;

            fileDataService.saveResultsFile((ResultsFile) any);

        }
    };

    resultsToCsvService.persistResultsAsCSV(id);

}

3 个答案:

答案 0 :(得分:4)

我是JMockit的创始人,但我很高兴地说'不要使用JMockit&#34;对此。

可以模拟Java IO类,但这几乎不是一个好主意;相反,在本地文件系统上使用真实文件。您的测试将更简单,更不易碎,并且足够快(除非您做一些不好的事情,比如读/写大文件,大量文件或访问慢速远程目录 - 但这些都不会出现在写得很好的测试中)。

当人们模拟IO API(即FileFileWriter等)时,他们不可避免地会得到一个与被测代码的实现紧密耦合的测试,因此很复杂而且很脆弱。在实践中,让测试触及文件系统会更好;如果这使它成为一个集成测试&#34;,那就这样吧。

答案 1 :(得分:1)

您应该重构您的测试方法,以便为其提供输出流或编写器,而不是让它自己打开文件。这通常是一个好主意,即使在单元测试的上下文之外,因为它使代码更可重用;例如,您可能希望将输出写入套接字或压缩流。

答案 2 :(得分:0)

应该使用规则(最愚蠢的名字,实际上与规则本身无关)。

Rules for Files in Unit Tests