如何解决依赖于 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 类,因此在测试中肯定会尝试使用不理想的真实数据。我正在考虑使用模拟来传递假数据,但不确定它是如何工作的。我对 moq 不太熟悉,但我假设我想创建一个模拟来将测试数据传递到 ReadFromFile 并检查预期结果是否正确?
其次,我使用依赖注入来移除 CsvReader 和 CsvParser 之间的依赖,特别是 ParseRow 方法。我知道我可以使用 moq 来模拟接口 + 方法,但是由于在 foreach 循环中调用了 PraseRow,这将如何影响设置?也就是说每次调用返回的值都会不同?
解决方法
首先我的代码耦合/依赖于 File 类
作为一般规则,尝试编写可以将流作为输入的 API。你可以有一个额外的方法来获取文件路径,打开文件并将流转发到另一个方法。但这主要是为了方便。当您拥有内存流或其他数据源并被迫将其保存到临时文件时,仅采用文件路径的 API 会非常烦人。
如果采用文件路径的方法几乎没有逻辑,那么对其进行单元测试的好处就更少了。如果它只打开一个文件,我只会通过代码审查而感到满意。并不是每一行代码都需要被单元测试覆盖。或者更确切地说,单元测试的收益/成本比率因代码类型而异。
在测试中肯定会尝试使用不理想的真实数据
我认为使用真实数据进行单元测试不一定是坏事。当然,如果数据量很小,最好使用硬编码的字符串或字节数组作为测试数据的来源。但是,在您的测试项目中添加一个更大、更复杂的文件作为内容文件并使用该文件编写测试也可能很有用。这会在一定程度上减慢单元测试的速度。如果这是一个问题,解决方案可以是将使用 IO 的测试放在运行频率较低的特殊类别中。
我知道我可以使用 moq 来模拟接口 + 方法,但是由于在 foreach 循环中调用了 PraseRow,这将如何影响设置?
如果需要,您仍然可以一起测试这两个类。对于这样的类,我可能会认为它们的耦合度如此之高,以至于单独测试它们不会增加太多好处。 IE。您应该考虑单独测试它们的好处是否大于额外成本。
也就是说每次调用返回的值都会不同?
这取决于你。编写每次返回相同值的模拟更容易。但是,如果您愿意,应该完全有可能从列表中返回行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。