文件解析和翻译的单元测试

时间:2017-12-13 07:12:47

标签: java unit-testing junit powermockito

如何为以下方法编写单元测试 - 以使其与输入文件无关?

似乎对业务对象的阅读和翻译是不同的职责 - 需要分开。

这将允许业务翻译可测试。

欢迎任何建议。

    public Map<header,record> createTradeFeedRecords(String tradeFile,String config) throws Exception {
        Map<header,record>  feedRecordMap = 
                new LinkedHashMap<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(tradeFile))) {
            for (String line; (line = reader.readLine()) != null;) {
                if (line.trim().isEmpty() || line.startsWith("#") )
                    continue;

                Record record = recordParser.extractTradeFeedRecord(line,config):
                feedRecordMap .put(record.getHeader(), record) ;

            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {

        }
        return feedRecordMap ;
    }

1 个答案:

答案 0 :(得分:3)

您可以使用JUnit的TemporaryFolder规则(或者,如果使用JUnit5,它的equivalent extension)来为您的测试创建输入文件。然后,您将在tradeFile参数中提供此文件的路径,并且您的测试将对您创建的文件进行操作。测试完成后,JUnit将丢弃临时文件夹,从而坚持自我遏制的测试原则。

我认为,这是最接近createTradeFeedRecords方法的实际行为的方法。

但是,如果您真的不想在测试中使用文件系统,或者确实如果您只想实现此目的......

  

似乎对业务对象的阅读和翻译是不同的职责 - 需要分开。

...然后你可以提取界面后面的new FileReader(tradeFile)调用。这样的事情,也许是:

public interface TradeReader {
    Reader read(String input);
}

这是'正常'的实现:

public class FileTradeReader implements TradeReader {
    @Override
    public Reader read(String input) {
        return new FileReader(input);
    }
}

然后,您可以提供此实现,以便在您的测试用例中使用:

public class StubTradeReader implements TradeReader {
    @Override
    public Reader read(String input) {
        return new StringReader(input);
    }
}

在测试中,您将使用createTradeFeedRecords的实例注入被测试类(即包含StubTradeReader的类)。通过这种方式,在您的测试中调用的createTradeFeedRecords方法将根据您在创建StubTradeReader时提供的任何输入进行操作,并且您的测试将不会与文件系统进行交互。

您还可以单独测试TradeReader(可能使用上面概述的临时文件夹方法),从而实现将阅读,翻译和测试分开的目标。