微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

依赖于 File 类和其他方法的测试方法

如何解决依赖于 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?