Использование «друзей» -декларации для модульного тестирования. Плохая идея? - PullRequest
17 голосов
/ 04 ноября 2008

[ Конечно, вопрос не ограничен конкретной «дружественной» реализацией, хотя вы можете указать на особенности реализации, если это уместно ]

Читая оставшиеся без ответа вопросы, я наткнулся на атрибут InternalsVisibleTo:

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

Руководство по программированию C # на MSDN содержит раздел Friend Assemblies , описывающий, как использовать атрибут, чтобы разрешить использование методов и типов internal для другая сборка.

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

Какой у вас опыт использования объявлений друзей при тестировании? Это была твоя Серебряная пуля, или это начало Марша смерти?

Ответы [ 5 ]

13 голосов
/ 04 ноября 2008

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

Хотя использование [InternalsVisibleTo] действительно увеличивает сцепление, я считаю, что (незначительное) увеличение стоит выигрышей.

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

В противном случае связь минимальна - наличие атрибута [InternalsVisibleTo] в сборке кода и маркировка некоторых вещей как внутренних вместо частных (или защищенный внутренний вместо защищенный ).

(Обратите внимание, что здесь я игнорирую любые конструктивные изменения, вызванные использованием модульного тестирования, что является совершенно другим обсуждением.)

Атрибут [InternalsVisibleTo] требует строгого именования ваших сборок. Если вы этого еще не сделали, вы можете найти это немного обременительным, поскольку сборка со строгим именем может зависеть только от других сборок со строгим именем, что может привести к необходимости изменения нескольких сборок.

Правильный выбор атрибута может быть немного сложным, так как он должен включать открытый ключ вашей тестовой сборки. У IDesign есть полезный Инструмент сборки друзей , который создает атрибут в буфере обмена и готов к вставке. Рекомендуется.

13 голосов
/ 04 ноября 2008

Это единственное использование, которое я когда-либо лично применял к InternalsVisibleTo - и это было очень, очень удобно.

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

3 голосов
/ 07 ноября 2008

На самом деле, модульное тестирование - это только использование, для которого я смог заставить себя использовать InternalsVisibleToAttribute. Таким образом, вы можете реализовать большую часть ваших «закрытых» методов как внутренние, вместо того, чтобы предоставлять их инфраструктуре модульного тестирования для более инвазивного тестирования инвариантов внутреннего класса.

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

3 голосов
/ 07 ноября 2008

Я думаю, использование InternalsVisibleToAttribute для включения модульного тестирования вполне разумно. Мой «модуль» в «модульном тестировании» - это класс, который включает internal классы, поэтому я хочу их протестировать. Я не хочу юнит-тестирование private методы , хотя.

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

Однако я предпочитаю размещать мои модульные тесты в той же сборке, что и мой рабочий код. Обычно это не влияет на моего покупателя, но упрощает для меня вещи, поэтому я делаю это. Когда я это делаю, вопрос InternalsVisibleTo уходит.

2 голосов
/ 21 сентября 2010

Я думаю, что есть еще один законный вариант использования, когда вы использовали отдельные сборки при объединении унаследованного кода C ++ с более новым кодом C #.

Мы взяли сборки C ++, преобразовали их в C ++ / CLI, а затем внедрили более новый код в C #. Когда мы сделаем это, мы все равно будем использовать «internal» для классов / методов в C #, которые на самом деле не являются общедоступными, и затем делать их доступными для унаследованного кода в качестве сборок друзей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...