Як дозволити збірці (модульна перевірка однієї) отримати доступ до внутрішніх властивостей іншої збірки?


80

Я хотів би, щоб моя збірка Core не виставляла певний клас, і я все одно хотіла б мати можливість протестувати його. Як я можу це зробити?

Відповіді:


107

InternalsVisibleTo приписувати порятунку!

Просто додайте:

[assembly:InternalsVisibleToAttribute("UnitTestAssemblyName")]

до вашого базового файлу AssemblyInfo.cs

Див. Асамблеї друзів (Посібник із програмування на C #), щоб отримати найкращі практики.


3
Я просто зробив це успішно за допомогою сильної іменованої збірки, дотримуючись вказівок, на які посилається aku. У мене все-таки було одне питання. Після того, як все було налаштовано, мені довелося перезапустити Visual Studio, щоб Intellisense працював. Він компілюється перед перезапуском, але завжди відображає червоні лінії.
Ерік Шоновер,

20

Наприклад, за допомогою InternalsVisible, якщо ваші збірки мають іменоване ім'я, вам потрібно вказати відкритий ключ (примітка: повний ключ, а не маркер відкритого ключа), наприклад ...

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("BoardEx_BusinessObjects.Tests, 
  PublicKey=0024000004800000940000000602000000240000525341310004000001000100fb3a2d8 etc etc")]

і наступний трюк дійсно корисний для отримання відкритого ключа, не вдаючись до рядка cmd ...

http://www.andrewconnell.com/blog/archive/2006/09/15/4587.aspx


9

Я ставлю свої модульні тести в ту саму збірку, що і код, який він тестує. Для мене це має сенс, тому що я вважаю "перевірити себе" як особливість класу, поряд із такими речами, як "ініціалізувати себе" та "описати себе".

Я чув деякі заперечення проти цього підходу, але мало хто з них був переконливим.

Це шкодить продуктивності Бах, кажу! Не оптимізуйте без надійних даних! Можливо, якщо ви плануєте завантажувати свої збірки за повільними посиланнями, тоді мінімізація розміру збірки буде доцільною.

Це ризик для безпеки . Тільки якщо у вас є секрети в тестах. Не роби цього.

Зараз ваша ситуація відрізняється від моєї, тож, можливо, це матиме для вас сенс, а можливо, ні. Вам доведеться це зрозуміти самому.

Крім: У C # я якось спробував помістити свої модульні тести в клас із назвою "Тести", який був вкладений всередину класу, який він тестував. Це зробило очевидною правильну організацію речей. Він також уникнув дублювання імен, що виникає, коли тести для класу "Foo" знаходяться в класі під назвою "FooTests". Однак модульні модулі тестування, до яких я мав доступ, відмовились приймати тести, які не були позначені як "загальнодоступні". Це означає, що клас, який ви тестуєте, не може бути "приватним". Я не можу придумати жодної вагомої причини вимагати, щоб тести були "публічними", оскільки насправді їх ніхто не називає загальнодоступними методами - все відбувається через рефлексію. Якщо ви коли-небудь пишете фреймворк модульного тестування для .Net, будь ласка, ради мене дозвольте непублічні тести!


5
Цікавий підхід. І я повністю згоден з тим, що тести є загальнодоступними. Дурна вимога, ІМО.
Кілхоффер,

@Kilhoffer: Я нарікаю на це роками, і ти перша людина, яка справді погодилася зі мною. Дякую!
Джей Базузі,

6
Якщо ви використовуєте [Conditional("DEBUG")]на тестових класах, то вони не повинні знаходитись у виробничій збірці і не шкодити продуктивності.
xmedeko

3

Я б радив не переходити до таких проблем ... якщо ви дійсно хочете перевірити модульні свої "внутрішні" класи, просто сховайте їх у просторі імен, який в кінцевому підсумку використовуватиме лише ваш внутрішній код. Якщо ви не пишете рамки в масштабі платформи .NET, що не на самому ділі потрібно , що рівень приховування.


Я збирався прокоментувати саме те, що ви сказали, коли я помітив ваш коментар внизу. +1! :)
Bjorn Reppen

2

Ви можете використовувати відображення (як це роблять елементи тесту MS), або можете оголосити блок модульного тестування другом основного вузла.

Інший варіант - поставити модульні тести в ту саму збірку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.