фальшивые каталоги для модульного тестирования .net - PullRequest
1 голос
/ 19 апреля 2011

Я пытаюсь создать модульный тест для кода, подобного следующему:

foreach (string domainName in Directory.GetDirectories(server.Path))
{
     HandleDomainDirectory(session, server, domainName);
}

Проблема в том, что я использую класс System.IO.Directory в своем коде.Как я могу создать метод тестирования, который не будет зависеть ни от какой папки на моем жестком диске.Другими словами, как я могу подделать ответ "Directory.GetDirectories(server.Path)"?(Обратите внимание, что я контролирую объект «сервер» в своем классе, поэтому я могу указать любой путь, какой захочу)

Спасибо.

Ответы [ 4 ]

2 голосов
/ 19 апреля 2011

Вместо непосредственного вызова Directory.GetDirectories(server.Path) вы можете создать интерфейс типа IDirectoryResolver с помощью одного метода, который принимает строку пути и возвращает список каталогов.Классу, содержащему приведенный выше код, понадобится свойство или поле типа IDirectoryResolver, которое можно внедрить с помощью конструктора или установщика.

Для вашего производственного кода вы должны создать новый класс, который реализуетIDirectoryResolver интерфейс.Этот класс может использовать метод Directory.GetDirectories в своей реализации метода интерфейса.

Для модульного тестирования вы можете создать класс MockDirectoryResolver, который реализует IDirectoryResolver (или использовать библиотеку-макет для создания макетаэкземпляр для интерфейса).Макетная реализация может делать все, что вам нужно.

1 голос
/ 19 апреля 2011

Вы бы добавили класс оболочки.

public class DirectoryFetcher
{
     public virtual List<string> GetDirectoriesIn(string directory)
     {
          return Directory.GetDirectories(directory);
     }
}

А затем введите это:

foreach(string directory in _directoryFetcher.GetDirectoriesIn(server.Path))
{
    // Whatever
}

Затем вы можете смоделировать этого парня в точке инъекции (в этом примере используется Moq и инъекция конструктора):

Mock<DirectoryFetcher> mockFetcher = new Mock<DirectoryFetcher>();

mockFetcher.Setup(x => x.GetDirectoriesIn("SomeDirectory")).Returns(new List<string>
{
    "SampleDirectory1",
    "SampleDirectory2"
});

MyObjectToTest testObj = new MyObjectToTest(mockFetcher.Object);

// Do Test
0 голосов
/ 21 апреля 2011

Лучшим решением, которое я нашел, было использование Родинок . Код очень специфичен и должен делать очень специфические вещи. Упаковка с классом-оберткой будет излишней. Единственная причина, по которой мне понадобился класс-обертка, - чтобы писать тесты. Кроты позволяют мне писать тесты без каких-либо классов-обёрток:)

0 голосов
/ 19 апреля 2011

При общении с внешним миром, таким как файловая система, базы данных, веб-сервисы и т. Д., Вы всегда должны использовать классы-обертки, как и другие, предложенные мной ранее. Тестируемость - это один из основных аргументов, но еще более важный: внешний мир меняется, и вы не можете его контролировать. Папки перемещаются, права пользователей меняются, появляются новые диски и удаляются старые. Вы хотите заботиться о таких вещах только в одном месте. Следовательно, обертка - давайте назовем ее DirectoryResolver, как предложил Энди Уайт.

Итак, оберните вызовы вашей файловой системы, извлеките интерфейс и внедрите тот интерфейс, где вам нужно общаться с файловой системой.

...