Включение файла ресурсов для модульного теста в проекте C # - PullRequest
12 голосов
/ 20 июля 2010

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

Однако моя функция должна получать filePath, и все, что я могу получить из сборки, это FileStream.Любая идея, как я могу получить путь к файлу ресурса в проекте?

System.Reflection.Assembly a = System.Reflection.Assembly.Load(assemblyName);
FileStream stream = a.GetFile(assemblyName + "." + fileName);

Спасибо!

Ответы [ 4 ]

8 голосов
/ 20 июля 2010

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

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

Пример из одной из моих программ:

public TestSaveAndLoad()
{
  [... create data to save ...]
  using (MemoryStream targetStream = new MemoryStream())
  {
    target.Save(targetStream);
    targetStream.Flush();
    targetStream.Seek(0, ...);
    target.Load(targetStream);
  }
  [... assert that the loaded data equals the saved data ...]
}
4 голосов
/ 20 июля 2010

Встроенный ресурс не существует в файловой системе, поэтому у него нет пути к файлу.

У вас есть два варианта:

  • Изменить API вашего SUT , чтобы он принимал поток вместо только пути к файлу.Это решение гораздо предпочтительнее .
  • Сохраните встроенный ресурс во временный файл во время модульного тестирования, обязательно удаляя его снова после каждого теста.

Первое решение является отличным примером того, как TDD ведет нас к более совершенным, более гибким API .

1 голос
/ 20 июля 2010

Вы можете установить файлы данных для копирования в каталог bin при сборке проекта, а затем ссылаться на них с помощью Directory.GetCurrentDirectory () в своем тесте.Или даже оставьте их там, где они есть, и просто используйте относительный путь, основанный на текущем каталоге.

Лучше, однако, было бы реструктурировать ваш код с учетом класса Stream, а затем использовать комбинацию насмешек и внедрения зависимостей.предоставить фиктивный поток с данными - или использовать поток памяти, если подделка работает лучше.

0 голосов
/ 20 июля 2010

Если вы установили действие сборки файла для копирования, вы можете предсказать, где файл должен быть (вероятно, куча .. \ .. \ .. \ 'ы, но все же).Я предполагаю, что у вас есть вход для вашего метода для имени файла, так что это должно работать нормально.

Как совет, можно абстрагировать фактическое чтение / изменение этого файла в методи передать строковое значение?Единственная причина, по которой я привел это, состоит в том, что он пахнет интеграционным тестом (касающимся файловой системы).

...