Я пишу компонент, который, учитывая ZIP файл, должен:
- Разархивируйте файл.
- Найдите определенную dll среди распакованных файлов.
- Загрузите эту DLL через отражение и вызовите на ней метод.
Я хотел бы unit test этот компонент.
У меня возникает соблазн написать код, который напрямую связан с файловой системой:
void DoIt()
{
Zip.Unzip(theZipFile, "C:\\foo\\Unzipped");
System.IO.File myDll = File.Open("C:\\foo\\Unzipped\\SuperSecret.bar");
myDll.InvokeSomeSpecialMethod();
}
Но люди часто говорят: "Не пишите модульные тесты, которые полагаются на файловую систему, базу данных, сеть и т.д."
Если бы я написал это в дружественном модульном тестировании, я предполагаю, что это будет выглядеть так:
void DoIt(IZipper zipper, IFileSystem fileSystem, IDllRunner runner)
{
string path = zipper.Unzip(theZipFile);
IFakeFile file = fileSystem.Open(path);
runner.Run(file);
}
Ура! Теперь это можно проверить; Я могу комбинировать тестовые двойники (mocks) с методом DoIt. Но какой ценой? Теперь я должен был определить 3 новых интерфейса, чтобы сделать это возможным. И что, собственно, я тестирую? Я тестирую, что моя функция DoIt правильно взаимодействует со своими зависимостями. Он не проверяет правильность распаковки почтового файла и т.д.
Не похоже, что я больше тестирую функциональность. Похоже, я просто тестирую взаимодействия между классами.
Мой вопрос в том, что: какой правильный способ для unit test что-то зависит от файловой системы?
edit Я использую .NET, но в эту концепцию может также входить Java или собственный код.