Как мне издеваться над Directory.GetFiles? - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь выяснить, как или если возможно сделать следующее с Moq

public class Download
{
    private IFoo ifoo;

    public Download(IFoo ifoo)
    {
        this.ifoo = ifoo;
    }

    public void Download()
    {
        var files = Directory.GetFiles("filepath"); //<<<===

        foreach (var item in files)
        {

            // do something

        }    
    }
}

В модульном тесте.

// Arrange 

var mockFoo = new Mock<IFoo>();
mockFoo.setup( s => s.Bar()).returns(true);

var foo = new Foo(mockFoo.Object);

// Act
foo.Download()

Как можно смоделировать переменную files, чтобы метод использовал версию макета.Это даже правильный подход?Поскольку я не издеваюсь над классом, а скорее издеваюсь над зависимостью, как мне настроить параметры файлов, чтобы они смотрели на строку с поддельными файлами [].

1 Ответ

0 голосов
/ 04 декабря 2018

Вы должны зависеть от абстракции для получения ваших файлов вместо жесткой зависимости от 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"} );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...