Вопрос

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

FieldInfo[] _fields = 
    typeof(ButtonedForm.TitleButton).GetFields(
        BindingFlags.NonPublic | BindingFlags.Instance | 
        BindingFlags.DeclaredOnly);
Console.WriteLine("{0} fields:", _fields.Length);
foreach (FieldInfo fi in _fields)
{
    Console.WriteLine(fi.Name);
}

Это хорошо отображает всех частных членов, но все равно не отображает внутренние компоненты.Я знаю, что это возможно, потому что, когда я возился с автоматически сгенерированными тестами, которые может создавать Visual Studio, она спросила, что связано с отображением внутренних компонентов тестового проекта.Что ж, сейчас я использую NUnit, и он мне очень нравится, но как я могу добиться с его помощью того же самого?

Это было полезно?

Решение

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

Вот ссылка с некоторой полезной дополнительной информацией и пошаговым руководством:

Чтобы ответить на ваш вопрос...Внутренние и защищенные не распознаются в API .NET Reflection.Вот цитата из MSDN:

Ключевые слова C# protected и Internal не имеют значения в IL и не используются в API-интерфейсах Reflection.Соответствующие термины в ИЛ — Семья и Собрание.Чтобы идентифицировать внутренний метод с помощью Reflection, используйте IsAssembly свойство.Чтобы идентифицировать защищенный внутренний метод, используйте IsFamilyOrAssembly.

Другие советы

Добавление InternalsVisibleTo атрибута уровня сборки В вашем основном проекте имя сборки для тестового проекта должно сделать видимыми внутренние элементы.

Например, добавьте следующее в свою сборку вне любого класса:

[assembly: InternalsVisibleTo("AssemblyB")]

Или для более точного таргетинга:

[assembly:InternalsVisibleTo("AssemblyB, PublicKey=32ab4ba45e0a69a1")]

Обратите внимание: если сборка вашего приложения имеет строгое имя, ваша тестовая сборка также должна иметь строгое имя.

Я думаю, вам нужно спросить, стоит ли писать модульные тесты для частных методов?Если вы пишете модульные тесты для своих общедоступных методов с «разумным» покрытием кода, разве вы уже не тестируете какие-либо частные методы, которые в результате должны быть вызваны?

Привязка тестов к частным методам сделает тесты более хрупкими.Вы должны иметь возможность изменить реализацию любых частных методов, не нарушая при этом никаких тестов.

Ссылки:

http://weblogs.asp.net/tgraham/archive/2003/12/31/46984.aspx http://richardsbraindump.blogspot.com/2008/08/should-i-unit-test-private-methods.html http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 http://geekswithblogs.net/geekusconlivus/archive/2006/07/13/85088.aspx

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

Есть ли в ButtonedForm.TitleButton какие-нибудь непубличные поля? Если вы пытаетесь найти внутренние методы , тогда, очевидно, вам нужно вызывать GetMethods (или GetMembers ), чтобы получить их.

Как и предполагали другие, InternalsVisibleTo очень удобен для тестирования (и почти исключительно для тестирования!). Что касается того, следует ли вам тестировать внутренние методы - я определенно считаю полезным иметь возможность сделать это. Я не рассматриваю юнит-тестирование как исключительно тестирование черного ящика. Часто, когда вы знаете, что открытая функциональность реализуется с помощью нескольких внутренних методов, связанных простым способом, проще провести тщательное тестирование каждого из внутренних методов и некоторые «псевдоинтеграции». тесты по публичному методу.

Обоснование использования InternalsVisible в моих обстоятельствах. Мы покупаем исходный код в Chart Control. Мы нашли, где нам нужно внести некоторые изменения в этот источник контроля и скомпилировать нашу собственную версию. Теперь, чтобы убедиться, что мы ничего не сломали, нужно написать несколько модульных тестов, которым нужен доступ к некоторым внутренним полям.

Это идеальный случай, когда InternalsVisible имеет смысл.

Мне было интересно, однако, что вы делаете, если у вас нет доступа к источнику? Как вы могли добраться до внутреннего поля? .Net Reflector может видеть этот код, но я думаю, он просто смотрит на IL.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top