Существуют ли какие-либо библиотеки или методы для моделирования файловой системы в C # для написания модульных тестов? В моем текущем случае у меня есть методы, которые проверяют, существует ли определенный файл и читают дату создания. Мне может понадобиться больше, чем это в будущем.
c#
unit-testing
mocking
pupeno
источник
источник
Ответы:
Редактировать: установить пакет NuGet
System.IO.Abstractions
.Этот пакет не существовал, когда этот ответ был первоначально принят. Оригинальный ответ предоставляется для исторического контекста ниже:
источник
Эта воображаемая библиотека существует сейчас, есть пакет NuGet для System.IO.Abstractions , который абстрагирует пространство имен System.IO.
Существует также набор помощников по тестированию System.IO.Abstractions.TestingHelpers, который на момент написания статьи реализован лишь частично, но является очень хорошей отправной точкой.
источник
Возможно, вам придется создать контракт, чтобы определить, что вам нужно из файловой системы, а затем написать оболочку для этих функций. В этот момент вы сможете высмеять или заглушить реализацию.
Пример:
источник
Я рекомендую использовать http://systemwrapper.codeplex.com/, поскольку он предоставляет оболочки для наиболее часто используемых типов в пространстве имен System.
источник
Я столкнулся со следующими решениями для этого:
В итоге я использую все методы, описанные выше, в зависимости от того, что я пишу. Но в большинстве случаев я думаю, что абстракция неправильна, когда я пишу модульные тесты, которые попадают в ввод-вывод.
источник
Используя System.IO.Abstractions и System.IO.Abstractions.TestingHelpers, вот так:
В своем тестовом классе вы используете MockFileSystem () для имитации файла и создаете экземпляр ManageFile, например:
источник
Вы можете сделать это с помощью Microsoft Fakes без необходимости менять код, например, потому что он уже заморожен.
Сначала создайте поддельную сборку для System.dll - или любого другого пакета, а затем смоделируйте ожидаемые результаты, как в:
источник
Было бы трудно смоделировать файловую систему в тесте, поскольку файловые API-интерфейсы .NET на самом деле не основаны на интерфейсах или расширяемых классах, которые можно было бы смоделировать.
Однако, если у вас есть свой собственный функциональный уровень для доступа к файловой системе, вы можете сделать это в модульном тесте.
В качестве альтернативы насмешкам, рассмотрите просто создание папок и файлов, которые вам нужны, как часть вашей тестовой настройки, и удаление их в вашем методе разрыва.
источник
Я не уверен, как вы будете копировать файловую систему. Что вы можете сделать, это написать настройку тестового устройства, которая создает папку и т. Д. С необходимой структурой для тестов. Метод демонтажа очистит его после запуска тестов.
Отредактировано, чтобы добавить: Размышляя об этом немного больше, я не думаю, что вы хотите издеваться над файловой системой для тестирования методов этого типа. Если вы дразните файловую систему, чтобы она возвращала true, если определенный файл существует, и используете его в своем тесте метода, который проверяет, существует ли этот файл, то вы ничего не тестируете. В противном случае было бы полезно использовать макетирование файловой системы, если вы хотите протестировать метод, который зависит от файловой системы, но активность файловой системы не является неотъемлемой частью тестируемого метода.
источник
Чтобы ответить на ваш конкретный вопрос: Нет, нет библиотек, которые позволили бы вам имитировать файловые вызовы ввода / вывода (о которых я знаю). Это означает, что для «правильного» модульного тестирования ваших типов потребуется учитывать это ограничение при определении типов.
Краткое примечание о том, как определить «правильный» модульный тест. Я считаю, что модульные тесты должны подтвердить, что вы получите ожидаемый результат (будь то исключение, вызов метода и т. Д.) При условии известных входных данных. Это позволяет вам настроить условия вашего модульного теста как набор входов и / или входных состояний. Лучший способ сделать это - использовать основанные на интерфейсе сервисы и внедрение зависимостей, чтобы каждая ответственность, внешняя по отношению к типу, обеспечивалась через интерфейс, передаваемый через конструктор или свойство.
Итак, помня об этом, вернемся к вашему вопросу. Я смоделировал вызовы файловой системы, создав
IFileSystemService
интерфейс вместе сFileSystemService
реализацией, которая представляет собой просто фасад методов файловой системы mscorlib. Мой код используетIFileSystemService
типы, а не mscorlib. Это позволяет мне подключить мой стандарт,FileSystemService
когда приложение работает, или смоделироватьIFileSystemService
в моих модульных тестах. Код приложения один и тот же независимо от того, как он выполняется, но базовая инфраструктура позволяет легко тестировать этот код.Я признаю, что использовать оболочку вокруг объектов файловой системы mscorlib очень сложно, но в этих конкретных сценариях стоит дополнительной работы, поскольку тестирование становится намного проще и надежнее.
источник
Создание интерфейса и проверка его для тестирования - самый чистый путь. Однако в качестве альтернативы вы можете взглянуть на Microsoft Moles Framework.
источник
Общим решением является использование некоторого абстрактного API файловой системы (например, Apache Commons VFS для Java): вся логика приложения использует API, а модульное тестирование позволяет имитировать реальную файловую систему с реализацией заглушки (эмуляция в памяти или что-то в этом роде).
Для C # существует похожий API: NI.Vfs, который очень похож на Apache VFS V1. Он содержит реализации по умолчанию как для локальной файловой системы, так и для файловой системы в памяти (последняя может использоваться в модульных тестах из коробки).
источник
В настоящее время мы используем проприетарный механизм обработки данных, и его API не представлен в качестве интерфейсов, поэтому мы вряд ли сможем выполнить модульное тестирование нашего кода доступа к данным. Затем я пошел с подходом Мэтта и Джозефа.
источник
Я бы пошел с ответом Джейми Иде. Не пытайтесь издеваться над тем, что вы не написали. Будут всевозможные зависимости, о которых вы не знали - закрытые классы, не виртуальные методы и т. Д.
Другой подход заключается в том, чтобы обернуть методы appopiate чем-то, что является насмешливым. Например, создайте класс с именем FileWrapper, который разрешает доступ к методам File, но это то, что вы можете макетировать.
источник