c# - 文件 IO 的单元测试方法

标签 c# unit-testing mocking tdd nunit

我正在努力养成编写单元测试的习惯,我以前写过一些,但它们通常都很基础......我想开始转向 TDD,因为我想提高我的代码(设计和结构)的质量 - 减少耦合,同时希望减少滑入可测试构建的回归数量。

我从一个相对简单的项目开始。生成的程序监视一个文件夹,然后对该文件夹中的文件进行操作。

下面是从项目中提取的一些代码的典型示例:

private string RestoreExtension(String file)
    {
        var unknownFile = Path.GetFileName(file);
        var ignoreDir = Path.GetDirectoryName(file) + "\\Unknown";
        string newFile;

        //We need this library for determining mime
        if (CheckLibrary("urlmon.dll"))
        {
            AddLogLine("Attempting to restore file extension");
            var mime = GetMimeType(BufferFile(file, 256));
            var extension = FileExtensions.FindExtension(mime);
            if (!String.IsNullOrEmpty(extension))
            {
                AddLogLine("Found extension: " + extension);
                newFile = file + "." + extension;
                File.Move(file, newFile);
                return newFile;
            }
        }
        else
        {
            AddLogLine("Unable to load urlmon.dll");
        }

        AddLogLine("Unable to restore file extension");

        if (!Directory.Exists(ignoreDir))
        {
            Directory.CreateDirectory(ignoreDir);
        }
        var time = DateTime.Now;
        const string format = "dd-MM-yyyy HH-mm-ss";

        newFile = ignoreDir + "\\" + unknownFile + "-" + time.ToString(format);
        File.Move(file, newFile);

        return String.Empty;
    }

问题:

如何使用 IO 测试方法? 我真的不想使用真实文件,因为这会很慢(而且更多的是集成测试?),但我真的看不到另一种方式。我可以添加一个可切换的 IO 抽象层,但在我看来这可能会使代码不必要地复杂化......

这样的项目值得进行单元测试吗? 我的意思是,它是否太简单了。一旦删除 .Net 和第 3 方库调用,就没有多少剩余了……那么,使其可测试的工作量是否意味着它不是一个好的测试候选者?

这个项目中的很多方法都是私有(private)的,因为这个项目恰好是一个windows服务。我读过你应该只真正测试外部可见的方法(公共(public)或通过接口(interface)公开),但在这种情况下我不太可能想要公开我自己的任何方法。那么这个项目是否值得测试(因为 id 可能需要将方法访问修饰符更改为 public 或添加一些属性以便 NUnit 可以看到它们)?

最佳答案

关于如何测试文件I/O: 一种常见的做法是将文件 I/O 封装在包装类中。例如:

public class FileHandler : IFileHandler
{
     public string GetFilename(string name)
     {
         return System.IO.GetFileName(name);
     }

    public string GetDirectoryName(string directory)
    {
         return System.IO.GetDirectoryName(directory);
    }
}

public interface IFileHandler
{
      string GetFilename(string name);
      string GetDirectoryName(string directory);
}

在您的被测方法中,您仅针对接口(interface)进行编程。当您运行单元测试时,您将使用一个返回预定义值的模拟对象。为此,您可以使用 Moq .

这需要做一些工作,但您也不需要测试文件 I/O。

最佳 简

关于c# - 文件 IO 的单元测试方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16541571/

相关文章:

c# - 我希望绑定(bind)到 WPF 列表中的列表

javascript - AngularJS 私有(private)功能单元测试困惑

perl - 模拟另一个模块内部使用的 Git 模块

c# - 在 Sharepoint 中使用 C# 为 Web 部件布置表单

c# - AES 加密 - 加密/解密添加额外字节

c# - 存储 blob 复制操作期间出错 - 实体的当前状态不允许请求的操作

unit-testing - 使 typescript 编译器忽略一行或接受一个错误声明的函数(TSX)

unit-testing - 如何使用 jasmine 模拟 Angular 服务?

python - 如何模拟 boto3 客户端对象/调用

php - PHPUnit 模拟对象是否可以替换类中创建的对象?