文件解析和翻译的单元测试
Unit tests for file parsing and translation
如何为以下方法编写单元测试 - 使其与输入文件无关?
似乎读取和转换为业务对象是不同的职责——需要分开。
这将使业务翻译成为可测试的。
欢迎提出任何建议。
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 ;
}
您可以使用 JUnit TemporaryFolder rule (or, if using JUnit5, its equivalent extension) 为您的测试创建一个输入文件。然后,您将在 tradeFile
参数中提供该文件的路径,您的测试将对您创建的文件进行操作。在测试完成后JUnit会丢弃临时文件夹,从而坚持自包含的测试原则。
我认为,这是最接近 createTradeFeedRecords
方法的 实际 行为的方法。
但是,如果您真的不想在测试中使用文件系统,或者您确实只是想实现这一点..
It seems that the reading and translation into business objects are distinct responsibilities - which need to be separate.
... 然后您可以提取接口后面的 new FileReader(tradeFile)
调用。可能是这样的:
public interface TradeReader {
Reader read(String input);
}
'normal' 的实现是:
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);
}
}
在你的测试中,你将注入 class-under-test(即包含 createTradeFeedRecords
的 class)和 StubTradeReader
的实例。这样,在您的测试中调用的 createTradeFeedRecords
方法将根据您在创建 StubTradeReader
时提供的任何输入起作用,并且您的测试不会与文件系统进行交互。
您也可以单独测试TradeReader
(也许使用上面概述的临时文件夹方法),从而实现分离阅读和翻译并独立测试的目标。
如何为以下方法编写单元测试 - 使其与输入文件无关?
似乎读取和转换为业务对象是不同的职责——需要分开。
这将使业务翻译成为可测试的。
欢迎提出任何建议。
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 ;
}
您可以使用 JUnit TemporaryFolder rule (or, if using JUnit5, its equivalent extension) 为您的测试创建一个输入文件。然后,您将在 tradeFile
参数中提供该文件的路径,您的测试将对您创建的文件进行操作。在测试完成后JUnit会丢弃临时文件夹,从而坚持自包含的测试原则。
我认为,这是最接近 createTradeFeedRecords
方法的 实际 行为的方法。
但是,如果您真的不想在测试中使用文件系统,或者您确实只是想实现这一点..
It seems that the reading and translation into business objects are distinct responsibilities - which need to be separate.
... 然后您可以提取接口后面的 new FileReader(tradeFile)
调用。可能是这样的:
public interface TradeReader {
Reader read(String input);
}
'normal' 的实现是:
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);
}
}
在你的测试中,你将注入 class-under-test(即包含 createTradeFeedRecords
的 class)和 StubTradeReader
的实例。这样,在您的测试中调用的 createTradeFeedRecords
方法将根据您在创建 StubTradeReader
时提供的任何输入起作用,并且您的测试不会与文件系统进行交互。
您也可以单独测试TradeReader
(也许使用上面概述的临时文件夹方法),从而实现分离阅读和翻译并独立测试的目标。