Вы должны зависеть от абстракции для получения ваших файлов вместо жесткой зависимости от System.IO.Directory
:
public interface IFileProvider
{
string[] GetFiles(string path);
}
public class PhysicalFileProvider : IFileProvider
{
public string[] GetFiles(string path)
{
return Directory.GetFiles(path);
}
}
Вы бы внедрили абстракцию точно так же, как вы вводитеIFoo
.Теперь вы можете макетировать IFileProvider
с помощью Moq, создавая макет, который возвращает именно те строки, которые вы хотите, чтобы он возвращал.
var fileProvider = new Mock<IFileProvider>();
fileProvider.Setup(x => x.GetFiles(It.IsAny<string>()))
.Returns(new[] {"file1.txt", "file2.txt"});
Вы также можете использовать Microsoft.Extensions.FileProviders.Physical который обеспечивает как доступ к файловой системе, так и абстракцию.
public class Download
{
private readonly IFoo _foo;
private readonly Microsoft.Extensions.FileProviders.IFileProvider _fileProvider;
public Download(IFoo foo, IFileProvider fileProvider)
{
_foo = foo;
_fileProvider = fileProvider;
}
public void SomethingWithFiles()
{
var files = _fileProvider.GetDirectoryContents("filepath")
.Where(item => !item.IsDirectory);
foreach (var item in files)
{
// something
}
}
}
Конкретная реализация будет PhysicalFileProvider
.
Еще один вариант.Вместо внедрения интерфейса вставьте делегата:
public delegate string[] GetFilesFunction(string path);
public class Download
{
private readonly IFoo _foo;
private readonly GetFilesFunction _getFiles;
public Download(IFoo foo, GetFilesFunction getFiles)
{
_foo = foo;
_getFiles = getFiles;
}
...
Это даже проще для насмешки.Вам даже не нужен Moq.
var subject = new Download(mockedFoo, path => new []{"file1.txt","file2.txt"} );