В .NET, TypeMock Isolator и Microsoft Moles позволяют изолировать любой класс, свойство или метод - будь то запечатанным, статическим, защищенным или не виртуальным. Так что невозможно было издеваться над моком или носорогами, теперь уже не так.
У меня всегда было какое-то отвращение к идее использования интерфейса просто для того, чтобы позволить насмехаться, когда иначе будет существовать только конкретный класс. Я не одинок в этом представлении (см. здесь, здесь и здесь). В дальнейшем это подразумевало, что "современные" издевательские рамки больше не нуждаются в интерфейсах для тестирования или инъекции зависимостей.
Однако, хотя я не могу говорить о TypeMock Isolator, могу сказать, что использование Mocks в Microsoft Moles очень медленное. Наличие в модульных тестах кода, подобного приведенному ниже, позволяет слишком быстро использовать скорость теста:
MFile.ReadAllLinesString = (s) => csvDataCorrectlyFormatted;
MDirectoryInfo.AllInstances.GetFilesString = (di,fi) => fileInfoArray;
MFileInfo.AllInstances.NameGet = (fi) => "Doesn't Matter";
Я уверен, что если тестируемый метод был запрограммирован на интерфейс или абстрактный базовый класс (так что код файловой системы можно было бы отвлечь в виде обертки), что использование фреймворков, таких как Moq для укупорки или издевательств, закончилось бы быстрее. Но потом мы вернулись к ситуации, когда добавили сложность производственного кода в основном для возможности unit test.
Я склоняюсь к мнению, что Isolator и Moles следует использовать только тогда, когда нельзя смешиваться с традиционными издевательскими фреймворками. Тем не менее, я все еще борюсь с понятием добавления сложности производственного кода для тестирования.
Мне любопытно, что думает остальная часть сообщества.
ОБНОВЛЕНИЕ 10/06/10: Говоря, что я борюсь с понятием добавления сложности производственного кода для тестирования, я имею в виду добавление интерфейса (или абстрактного класса даже), когда в противном случае не требуется, например, при создании конкретного класса без запечатывания и виртуальных методов. Последний по-прежнему позволяет проводить испытания швов. Даже если позже выясняется необходимость использования интерфейса для нескольких реализаций, не могли ли они извлечь его из класса? Но если это не возникнет, почему бы не следовать YAGNI.
Я все для принципов SOLID, где они упрощают поддержку архитектуры программы. Я не думаю, что в каждом случае эти принципы должны соблюдаться религиозно. Я думаю, что мантра, "Это всегда зависит", вступает в игру много раз. В противном случае, каждый остается с каждым конкретным типом, имеющим интерфейс или абстрактный базовый класс, даже если будет только одна реализация.
Наконец, я не говорю об этом, потому что Isolator и Moles позволяют обойти ограничения изоляции в инфраструктурах с динамическим прокси-сервером, которые не должны до сих пор разрабатывать архитектуру для поддержки. Во многих случаях принципы SOLID являются лучшими, и поэтому Изолятор или Родинки не нужны. Это случаи, когда интерфейс используется исключительно для тестирования, который я допрашиваю. Я поднимаю еще одну боковую точку относительно скорости. Если вы решите использовать Isolator и Moles, это, как представляется, приведет к штрафу за скорость. Поэтому я, конечно, не думаю, что они делают устаревшие структуры на основе динамического прокси.