首页 > 解决方案 > 依赖于 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 循环中被调用,这将如何影响设置?换句话说,每次调用的返回值都会不同?

标签: c#unit-testingmethodsmoq

解决方案


首先,我的代码耦合/依赖于 File 类

作为一般规则,尝试编写可以将作为输入的 API。您可以使用其他方法来获取文件路径,打开文件并将流转发到其他方法。但这主要是为了方便。当您有内存流或其他数据源并被迫将其保存到临时文件时,仅采用文件路径的 API 非常烦人。

如果采用文件路径的方法包含很少的逻辑,那么对其进行单元测试的好处就更少了。如果它只打开一个文件,我只会对代码审查感到满意。并非每一行代码都需要被单元测试覆盖。或者更确切地说,单元测试的收益/成本比取决于它是什么类型的代码。

当然在测试中它会尝试使用不理想的真实数据

我认为使用真实数据进行单元测试不一定是坏事。当然,如果数据量很小,最好简单地使用硬编码的字符串或字节数组作为测试数据的来源。但在您的测试项目中添加一个更大、更复杂的文件作为内容文件并使用该文件编写测试也可能很有用。这会稍微减慢单元测试的速度。如果这是一个问题,解决方案是将使用 IO 的测试放在运行频率较低的特殊类别中。

我知道我可以使用 moq 来模拟接口 + 方法,但是由于 PraseRow 在 foreach 循环中被调用,这将如何影响设置?

如果需要,您仍然可以同时测试这两个类。对于像这样的类,我可能会认为它们耦合得如此之强,以至于单独测试它们不会增加太多好处。即您应该考虑单独测试它们的好处是否超过了额外的成本。

换句话说,每次调用的返回值都会不同?

它是由你决定。编写一个每次都返回相同值的模拟更容易。但是,如果您愿意,应该完全可以从列表中返回行。


推荐阅读