c# - 依赖于 File 类和其他方法的测试方法
问题描述
所以我创建了一个 CsvParser 来读取文件的内容并解析该文件的每一行/行。我有以下逻辑:
public interface ICsvReader {
List<string> ReadFromFile(string path);
}
public class CsvReader : ICsvReader
{
private readonly ICsvParser _csvParser;
public CsvReader(ICsvParser csvParser)
{
_csvParser = csvParser;
}
public List<string> ReadFromFile(string path)
{
if (!File.Exists(path)) return null;
var content = File.ReadAllLines(path);
return ParseContent(content);
}
private List<string> ParseContent(StreamReader input)
{
List<string> rows = new List<string>();
foreach (var line in lines) {
var updatedRow = _csvParser.ParseRow(line);
lines.Add(updatedRow);
}
return rows;
}
}
public interface ICsvParser
{
string ParseRow(string row);
}
public CsvParser : ICsvParser
{
public string ParseRow(string row)
{
// Performing parsing here returning parsed row
}
}
这可行,但是需要为其编写测试。这是我遇到问题的地方,并且对如何解决这个问题有些困惑。首先,我的代码耦合/依赖于 File 类,因此在测试中它肯定会尝试使用不理想的真实数据。我正在考虑使用模拟来传递虚假数据,但不确定它是如何工作的。我对起订量不太熟悉,但我假设我想创建一个模拟来将测试数据传递到 ReadFromFile 并检查预期结果是否正确?
其次,我使用依赖注入来删除 CsvReader 和 CsvParser 之间的依赖关系,特别是 ParseRow 方法。我知道我可以使用 moq 来模拟接口 + 方法,但是由于 PraseRow 在 foreach 循环中被调用,这将如何影响设置?换句话说,每次调用的返回值都会不同?
解决方案
首先,我的代码耦合/依赖于 File 类
作为一般规则,尝试编写可以将流作为输入的 API。您可以使用其他方法来获取文件路径,打开文件并将流转发到其他方法。但这主要是为了方便。当您有内存流或其他数据源并被迫将其保存到临时文件时,仅采用文件路径的 API 非常烦人。
如果采用文件路径的方法包含很少的逻辑,那么对其进行单元测试的好处就更少了。如果它只打开一个文件,我只会对代码审查感到满意。并非每一行代码都需要被单元测试覆盖。或者更确切地说,单元测试的收益/成本比取决于它是什么类型的代码。
当然在测试中它会尝试使用不理想的真实数据
我认为使用真实数据进行单元测试不一定是坏事。当然,如果数据量很小,最好简单地使用硬编码的字符串或字节数组作为测试数据的来源。但在您的测试项目中添加一个更大、更复杂的文件作为内容文件并使用该文件编写测试也可能很有用。这会稍微减慢单元测试的速度。如果这是一个问题,解决方案是将使用 IO 的测试放在运行频率较低的特殊类别中。
我知道我可以使用 moq 来模拟接口 + 方法,但是由于 PraseRow 在 foreach 循环中被调用,这将如何影响设置?
如果需要,您仍然可以同时测试这两个类。对于像这样的类,我可能会认为它们耦合得如此之强,以至于单独测试它们不会增加太多好处。即您应该考虑单独测试它们的好处是否超过了额外的成本。
换句话说,每次调用的返回值都会不同?
它是由你决定。编写一个每次都返回相同值的模拟更容易。但是,如果您愿意,应该完全可以从列表中返回行。
推荐阅读
- swift - NetService 无法发布
- angular - Angular路由器在检索状态对象时如何将window.history.state转换为一个类
- r - 自动化合并数据框添加一条线以记录原点
- python - 如何在python中将任何视频格式转换为mp4格式
- android - 无法在 Android 模拟器上启动“HelloWorld”NativeScript 应用程序
- mysql - MySQL 自动日期生成
- mysql - XAMPP manager-osx MySQL 数据库关闭 - 但 MySQL Workbench 中的状态为开启
- pandas - AttributeError:“DataFrame”对象没有属性“Recovery”
- javascript - 如何遍历数字数组并将它们与具有相同ID的对象数组匹配
- flutter - 谷歌字体包在颤振中不起作用