简体   繁体   English

单元测试时找不到目录

[英]Directory not found while unit testing

When I execute my test case, it fails for path within my machine which doesn't exist and I am getting below error: 当我执行我的测试用例时,它失败了我的机器中不存在的路径并且我得到以下错误:

System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Data1'. System.IO.DirectoryNotFoundException:找不到路径'C:\\ Data1'的一部分。

Do I need some kind of fake/mock here to pass the test case or do we have other way to do this? 我是否需要某种假/模拟来通过测试用例或者我们还有其他方法可以做到这一点吗?

Class

public class DemoCls
{
    public void Execute()
    {
        string dataFolder = @"C:\\Data1";
        foreach (string X in Directory.EnumerateFiles(dataFolder, "test" + "*.xml"))
        {
        }
    }
}

Test Case 测试用例

[TestClass()]
public class DemoClsTests
{
    [TestMethod()]
    public void ExecuteTest()
    {
        var X = new DemoCls();
        X.Execute();
    }
}

Class should be refactored to remove tight coupling to implementation concerns that make it difficult to test. 应该重构类以消除与实现问题的紧密耦合,这使得难以测试。

//...Creat an abstraction that provides the desired behavior as a contract
public interface IDirectoryService {
    IEnumerable<string> EnumerateFiles(string path, string searchPattern);
}

A fake/mock can be created for when testing to avoid pitfalls associated with testing IO code in isolation. 可以在测试时创建假/模拟,以避免与单独测试IO代码相关的陷阱。

A mocking framework could have been used for stubbing the dependencies, but for this example using a simple 可以使用模拟框架来存储依赖项,但对于此示例使用简单的

public class FakeDIrectoryService : IDirectoryService {
    IEnumerable<string> files;
    public FakeDIrectoryService(IEnumerable<string> files) {
        this.files = files;
    }
    public IEnumerable<string> EnumerateFiles(string path, string searchPattern = null) {
        return files;
    }
}

Class needs to be refactored now to follow Explicit Dependencies Principle via constructor and method injection. 现在需要重构类以通过构造函数和方法注入遵循显式依赖关系原则

public class DemoCls {
    IDirectoryService directory;
    public DemoCls(IDirectoryService directory) {
        this.directory = directory;
    }

    public void Execute(string dataFolder) {
        foreach (var x in directory.EnumerateFiles(dataFolder, "test*.xml")) {
            //...
        }
    }
}

Test can now be properly exercised in isolation. 现在可以单独适当地进行测试。

[TestClass()]
public class DemoClsTests {
    [TestMethod()]
    public void ExecuteTest() {
        //Arrange
        var fakePath = "C:/temp";
        var fakeFiles = new[] { 
            @"C:\\temp\\testfakefilename1.txt", 
            @"C:\\temp\\testfakefilename2.txt",
            @"C:\\temp\\testfakefilename3.txt" 
        };
        var service = new FakeDIrectoryService(fakeFiles);
        var sut = new DemoCls(service);

        //Act
        sut.Execute(fakePath);

        //Assert
        //perform your assertions
    }
}

Finally for production code the real implementation of the file service can wrap any source, be it disk or remote service. 最后,对于生产代码,文件服务的真正实现可以包装任何源,无论是磁盘还是远程服务。

For example 例如

public class FileService : IDirectoryService {
    public IEnumerable<string> EnumerateFiles(string path, string searchPattern) {
        return Directory.EnumerateFiles(path, searchPattern);
    }
}

This is just an example of what can be done. 这只是可以做的一个例子。 There is a lot of room for improvement but this should get things started. 还有很大的改进空间,但这应该可以开始。

Hardcoded paths are not good to have and I would recommend two options since the class is not static. 硬编码路径不好,我会推荐两个选项,因为类不是静态的。

1st 1

public class DemoCls
{
    public void Execute(string targetPath)
    {
        foreach (string X in Directory.EnumerateFiles(targetPath, "test" + "*.xml"))
        {
        }
    }
}

This keeps things more flexible and reusable 这使事情更加灵活和可重用

2nd 第2

public class DemoCls
{
    private string _targetPath;

    public DemoCls(string targetPath){
        _targetPath = targetPath;
    }
    public void Execute(string targetPath)
    {
        foreach (string X in Directory.EnumerateFiles(targetPath, "test" + "*.xml"))
        {
        }
    }
}

This way keeps the Execute method cleaner (less preferred) 这样可以使Execute方法更清洁(不太喜欢)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM