Как вы макете файловую систему в C # для модульного тестирования?

Существуют ли какие-либо библиотеки или методы для моделирования файловой системы в C # для написания модульных тестов? В моем текущем случае у меня есть методы, которые проверяют, существует ли определенный файл и читают дату создания. Мне может понадобиться больше, чем это в будущем.

 Guillaume8630 окт. 2013 г., 21:23
я написалgithub.com/guillaume86/VirtualPath для этой цели (и более) это все еще WIP, и API, безусловно, изменится, но он уже работает, и некоторые тесты включены.
 Steve Guidi07 июл. 2009 г., 01:36
@Mitch: в большинстве случаев достаточно поместить данные в файловую систему и позволить модульным тестам пройти свой курс. Однако я сталкивался с методами, которые выполняют много операций ввода-вывода, и настройка тестовой среды для таких методов значительно упрощается при использовании фиктивной файловой системы.
 Tinus06 июл. 2009 г., 17:07
Может быть, попробуйте заглянуть в Pex (research.microsoft.com/en-us/projects/pex/filesystem.pdf)
 John Saunders06 июл. 2009 г., 16:54
Это выглядит как дубликат нескольких других, в том числе:stackoverflow.com/questions/664277/….

Ответы на вопрос(13)

http://systemwrapper.codeplex.com/ так как он предоставляет оболочки для наиболее часто используемых типов в пространстве имен System

 03 мар. 2016 г., 20:31
IFileStreamWrap в SystemWrapper теперь реализует IDisposable.
 21 дек. 2013 г., 00:06
Я в настоящее время использую эту библиотеку, и теперь, когда я обнаружил, что ее абстракции для таких вещей, как FileStream, не включают IDisposable, я ищу замену. Если библиотека не позволяет мне правильно распоряжаться потоками, то я не могу рекомендовать (или использовать) ее для обработки операций такого рода.

ь. Тем не менее, в качестве альтернативы можно взглянуть наMicrosoft Moles фреймворк.

что вы не написали. Будут все виды зависимостей, о которых вы не знали - закрытые классы, не виртуальные методы и т. Д.

Другой подход заключается в том, чтобы обернуть методы appopiate чем-то, что является насмешливым. например создайте класс с именем FileWrapper, который разрешает доступ к методам File, но это то, что вы можете макетировать.

поскольку файловые API-интерфейсы .NET на самом деле не основаны на интерфейсах или расширяемых классах, которые можно было бы смоделировать.

Однако, если у вас есть свой собственный функциональный уровень для доступа к файловой системе, вы можете сделать это в модульном тесте.

В качестве альтернативы насмешкам рассмотрите просто создание папок и файлов, которые вам нужны, как часть вашей тестовой настройки, и удаление их в вашем методе разрыва.

овой системы (например,Apache Commons VFS для Java): вся логика приложения использует API, и модульное тестирование может имитировать реальную файловую систему с реализацией заглушки (эмуляция в памяти или что-то в этом роде).

Для C # существует аналогичный API:NI.Vfs который очень похож на Apache VFS V1. Он содержит реализации по умолчанию как для локальной файловой системы, так и для файловой системы в памяти (последняя может использоваться в модульных тестах из коробки).

Решение Вопроса

System.IO.Abstractions.

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

You could do it by creating an interface:

interface IFileSystem {
    bool FileExists(string fileName);
    DateTime GetCreationDate(string fileName);
}

and creating a 'real' implementation which uses System.IO.File.Exists() etc. You can then mock this interface using a mocking framework; I recommend Moq.

Edit: somebody's done this and kindly posted it online here.

I've used this approach to mock out DateTime.UtcNow in an IClock interface (really really useful for our testing to be able to control the flow of time!), and more traditionally, an ISqlDataAccess interface.

Another approach might be to use TypeMock, this allows you to intercept calls to classes and stub them out. This does however cost money, and would need to be installed on your whole team's PCs and your build server in order to run, also, it apparently won't work for the System.IO.File, as it can't stub mscorlib.

You could also just accept that certain methods are not unit testable and test them in a separate slow-running integration/system tests suite.

 18 окт. 2016 г., 07:24
Похоже, что репо в указанной статье было удалено / перемещено без уведомления. Тем не менее, здесь, кажется, есть полный пакет его усилий:nuget.org/packages/mscorlib-mock
 14 февр. 2013 г., 22:49
Лучшая библиотека, которую я когда-либо использовал для этогоsystemioabstractions.codeplex.com
 08 окт. 2017 г., 20:00
У Typemock есть ограничения на то, какие типы являются поддельными, но (по крайней мере, в текущей версии по состоянию на октябрь 2017 года) вы определенно можете подделать статический класс File. Я только что проверил это сам.
 07 июл. 2009 г., 01:32
На мой взгляд, создание интерфейса, как описывает Мэтт, - это путь. Я даже написал инструмент, который генерирует такие интерфейсы для вас, который полезен при попытке смоделировать статические и / или запечатанные классы, или недетерминированные методы (т.е. часы и генераторы случайных чисел). Увидетьjolt.codeplex.com для дополнительной информации.
 18 нояб. 2010 г., 16:26
Смотрите такжеsystemwrapper.codeplex.com

Нет, нет библиотек, которые позволили бы вам имитировать файловые вызовы ввода / вывода (о которых я знаю). Это означает, что «правильно» модульное тестирование ваших типов потребует, чтобы вы учитывали это ограничение при определении ваших типов.

Краткое примечание о том, как я определяю «правильное» модульный тест. Я считаю, что модульные тесты должны подтвердить, что вы получите ожидаемый результат (будь то исключение, вызов метода и т. Д.) При условии известных входных данных. Это позволяет вам настроить условия вашего модульного теста как набор входов и / или входных состояний. Наилучший способ, который я нашел для этого, - это использование основанных на интерфейсе сервисов и внедрение зависимостей, чтобы каждая ответственность, внешняя по отношению к типу, обеспечивалась через интерфейс, передаваемый через конструктор или свойство.

Итак, помня об этом, вернемся к вашему вопросу. Я смоделировал вызовы файловой системы, создавIFileSystemService интерфейс вместе сFileSystemService реализация, которая является просто фасадом над методами файловой системы mscorlib. Мой код затем используетIFileSystemService а не типы mscorlib. Это позволяет мне подключить мой стандартFileSystemService когда приложение работает или издеваетсяIFileSystemService в моих модульных тестах. Код приложения одинаков независимо от того, как он выполняется, но базовая инфраструктура позволяет легко тестировать этот код.

Я признаю, что использование оболочки вокруг объектов файловой системы mscorlib является болезненным, но в этих конкретных сценариях это требует дополнительной работы, поскольку тестирование становится намного проще и надежнее.

Microsoft подделок без необходимости менять свою кодовую базу, например, потому что она уже была заморожена.

Первыйсоздать поддельную сборку для System.dll - или любого другого пакета, а затем смоделируйте ожидаемые результаты, как в:

using Microsoft.QualityTools.Testing.Fakes;
...
using (ShimsContext.Create())
{
     System.IO.Fakes.ShimFile.ExistsString = (p) => true;
     System.IO.Fakes.ShimFile.ReadAllTextString = (p) => "your file content";

      //Your methods to test
}

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

Пример:

interface IFileWrapper { bool Exists(String filePath); }

class FileWrapper: IFileWrapper
{
    bool Exists(String filePath) { return File.Exists(filePath); }        
}

class FileWrapperStub: IFileWrapper
{
    bool Exists(String filePath) 
    { return (filePath == @"C:\myfilerocks.txt"); }
}

Install-Package System.IO.Abstractions

этоimaginary библиотека существует, есть пакет NuGet дляSystem.IO.Abstractions, который абстрагирует пространство имен System.IO.

Существует также набор помощников по тестированию System.IO.Abstractions.TestingHelpers, который на момент написания статьи реализован лишь частично, но является очень хорошей отправной точкой.

 14 февр. 2014 г., 19:13
Я думаю, что стандартизация вокруг этой уже построенной абстракции - лучший выбор. Никогда не слышал об этой библиотеке, так что большое спасибо за заголовки.
 20 мар. 2018 г., 19:06
PM означает менеджер пакетов ... чтобы открыть ... Инструменты & gt; Менеджер пакетов NuGet & gt; Консоль диспетчера пакетов

как вы будете копировать файловую систему. Что вы можете сделать, это написать настройку тестового устройства, которая создает папку и т. Д. С необходимой структурой для тестов. Метод демонтажа очистит его после запуска тестов.

Отредактировано, чтобы добавить: Думая об этом немного больше, я не думаю, что вы хотите смоделировать файловую систему для тестирования методов этого типа. Если вы пытаетесь заставить файловую систему вернуть значение true, если определенный файл существует, и использовать его в своем тесте метода, который проверяет, существует ли этот файл, то вы ничего не тестируете. В противном случае было бы полезно использовать макетирование файловой системы, если вы хотите протестировать метод, который зависит от файловой системы, но активность файловой системы не является неотъемлемой частью тестируемого метода.

х, и его API не представлен в качестве интерфейсов, поэтому мы вряд ли сможем выполнить модульное тестирование нашего кода доступа к данным. Затем я пошел с подходом Мэтта и Джозефа.

Write Integration tests, not unit tests. For this to work you need a simple way of creating a folder where you can dump stuff without worrying about other tests interfering. I have a simple TestFolder class which can create a unique per test method folder to use. Write a mockable System.IO.File. That is create a IFile.cs. I find using this often ends up with tests that simply prove you can write mocking statements, but do use it when the IO usage is small. Examine you layer of abstraction, and extract the file IO from the class. The create a interface for this. The remainder use integration tests (but this will be very small). This differs from above in that instead of doing file.Read you write the intent, say ioThingie.loadSettings() System.IO.Abstractions. I've not used this yet, but it is the one I'm most excited about playing with.

Я заканчиваю тем, что использую все методы выше, в зависимости от того, что я пишу. Но большую часть времени я думаю, что абстракция неправильна, когда я пишу модульные тесты, которые попадают в ввод-вывод.

 18 окт. 2016 г., 07:19
Ссылка на IFile.cs не работает.

Ваш ответ на вопрос