The target method under test is tightly coupled to static implementation concerns (Directory
).
So assuming a target SUT
public class AvailableFile {
public void GetAvailableFiles(string rootFolder) {
string[] files = Directory.GetFiles(rootFolder);
//...other code using files
}
}
Extract that out into an explicit service dependency.
public interface IDirectory {
string[] GetFiles(string rootFolder);
}
And refactor the SUT
public class AvailableFile {
private readonly IDirectory directory;
public AvailableFile (IDirectory directory) {
this.directory = directory;
}
public void GetAvailableFiles(string rootFolder) {
string[] files = directory.GetFiles(rootFolder);
//...other code using files
}
}
An implementation of the service in production can be done like
public class DirectoryServie : IDirectory {
public string[] GetFiles(string rootFolder) {
return Directory.GetFiles(rootFolder);
}
}
Making sure that the interface and implementation are registered with your IoC container in your composition root.
With all the decoupling done you can now test your implementations that depend on these services in isolation. You really want to be testing code you control and not 3rd partly implementations, which is what Directory
is. Microsoft would have tested that well enough.
Using Moq you can test you target system under test in isolation without any coupling to implementation concerns.
[Test]
public void CheckDirectory_Should_GetFiles() {
//Arrange
var files = new [] {
"fake path 1",
"fake path 2",
//fake path n
};
var rootPath = "C:\\Input";
var service = new Mock<IDirectory>();
service.Setup(_ => _.GetFiles(rootPath).Returns(files).Verifiable();
var fileUpload = new AvailableFile(service.Object);
//Act
fileUpload.GetAvailableFiles(rootPath);
//Assert
service.Verify();
}