[英]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.