Как издеваться над FileStream с System.IO.Abstraction? - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь использовать проект System.IO.Abstraction вместе с System.IO.Abstraction.TestingHelpers для макета FileStream.

. Этот код используетсяпоток файлов, который я хочу протестировать:

    private readonly IFileSystem _fileSystem;

    public void ExtractImageAndSaveToDisk(IXLPicture xlPicture, string filePath)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            xlPicture.ImageStream.CopyTo(ms);

            using (FileStream fs = (FileStream)_fileSystem.FileStream.Create(filePath, FileMode.Create))
            {
                ms.CopyTo(fs);
                fs.Flush();
                fs.Close(); 
            }
        }
    }

И вот как я настроил тестирование:

    [TestMethod]
    public void CheckFileIsSavedToDisk()
    {
        // Arrange
        var mockFileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
        {
            { @"c:\Test\Images\", new MockDirectoryData() },
        });

        var xlPicture = GetXLPicture();
        var filePath = @"c:\Test\Images\myimage.jpeg";

        var sut = new CostSheetImageExtractor(mockFileSystem);

        // Act
        sut.ExtractImagesAndSaveToDisk(xlPicture, filePath);
    }

При выполнении я получаю исключение:

System.InvalidCastException: Невозможно привести объект типа 'System.IO.Abstractions.TestingHelpers.MockFileStream' к типу 'System.IO.FileStream'.

в using (FileStream fs =...line.

Во-первых, мне нужно было изменить FileStream fs, чтобы использовать интерфейс, который разделяют как реальные, так и фиктивные объекты, но, насколько я вижу, нет интерфейса IFileStream, который FileStream и MockFileStream поделитесь, так что, полагаю, я делаю это совершенно неправильно?Есть ли способ протестировать этот код с помощью System.IO.Abstraction?

Этот существующий ответ , кажется, предполагает, что это возможно, я тоже пытался сделать это, но получил то же самоерезультаты.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Не издеваться над файловой системой - безусловно лучший вариант, как говорит Крис Ф. Кэрролл , но если вы действительно хотите это сделать, ваш вопрос почти содержит ответ.

КакВы сказали, что не существует такого понятия, как IFileStream интерфейс, но если вы посмотрите на определение FileStream, вы обнаружите, что он наследует абстрактный класс Stream, и это обычное явление.базовый класс для всех видов потоковых источников данных.Поддельный MockFileStream также должен наследовать оттуда.

Итак, попробуйте изменить свой код для использования абстрактного класса:

using (Stream fs = (Stream)_fileSystem.FileStream.Create(filePath, FileMode.Create))
{
    ms.CopyTo(fs);
    fs.Flush();
    fs.Close(); 
}

Он по-прежнему сохраняет все базовые методы и ваш код простоиспользует базовые.

0 голосов
/ 22 октября 2018

Моя первая реакция: вам почти никогда не нужно издеваться над файловой системой.У вас есть Real One, полностью работающий на вашей машине, на вашем сервере сборки и даже в ваших конвейерных контейнерах CI, и он работает действительно очень быстро.Так зачем издеваться?Похоже, на первый взгляд, это пустая трата времени.Пересмешка почти всегда является компромиссом с затратами, поэтому лучше не надругаться над ней.

То, что вы действительно хотите, если вы пойдете этим путем и протестируете файловую систему снова, это что-то вроде System.IO.Directory.GetCurrentDirectory() или System.IO.Path.GetTempPath() дляполучить место, которое ваш набор тестов может назвать своим, и надежно написать, прочитать и (необязательно) впоследствии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...