如何为以下方法编写单元测试 - 以使其与输入文件无关?
似乎对业务对象的阅读和翻译是不同的职责 - 需要分开。
这将允许业务翻译可测试。
欢迎任何建议。
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 ;
}
答案 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
(可能使用上面概述的临时文件夹方法),从而实现将阅读,翻译和测试分开的目标。