Я новичок в модульном тестировании, и я пытаюсь выяснить, должен ли я использовать больше "внутреннего" модификатора доступа. Я знаю, что если мы будем использовать "internal" и установить переменную сборки InternalsVisibleTo, мы можем протестировать функции, которые мы не хотим объявлять публикой из проекта тестирования. Это заставляет меня думать, что я всегда должен использовать "внутренний", потому что по крайней мере каждый проект (должен?) Имеет собственный проект тестирования. Можете ли вы, ребята, объяснить мне причину, почему я не должен этого делать? Когда следует использовать 'private'?
С# "внутренний" модификатор доступа при выполнении модульного тестирования
Ответ 1
Внутренние классы должны быть протестированы, и есть атрибут сборки:
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("MyTests")]
Добавьте это в файл информации о проекте, например. Properties\AssemblyInfo.cs
.
Ответ 2
Если вы хотите протестировать закрытые методы, взгляните на PrivateObject
и PrivateType
в пространстве имен Microsoft.VisualStudio.TestTools.UnitTesting
. Они предлагают простые в использовании обертки вокруг необходимого кода отражения.
Документы: PrivateType, PrivateObject
Для VS2017 и 2019 вы можете найти их, загрузив nuget MSTest.TestFramework
Ответ 3
Добавив к ответу Эрика, вы также можете настроить это в файле csproj
:
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>MyTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
Или если у вас есть один тестовый проект для каждого тестируемого проекта, вы можете сделать что-то подобное в вашем файле Directory.Build.props
:
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>$(MSBuildProjectName).Test</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
см.: fooobar.com/questions/723527/...
Пример: https://github.com/gldraphael/evlog/blob/master/Directory.Build.props#L5-L12
Ответ 4
Вы также можете использовать private и вызывать private методы с отражением. Если вы используете Visual Studio Team Suite, у него есть приятная функциональность, которая генерирует прокси для вызова ваших личных методов. Вот статья о проекте кода, которая демонстрирует, как вы можете выполнить работу самостоятельно, чтобы протестировать частные и защищенные методы:
http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx
С точки зрения того, какой модификатор доступа вы должны использовать, мое общее эмпирическое правило - начинать с приватного и увеличивать по мере необходимости. Таким образом, вы будете раскрывать как можно меньше внутренних деталей вашего класса, и это поможет скрыть детали реализации, как и должно быть.
Ответ 5
По умолчанию использовать личное. Если член не должен выставляться за пределами этого типа, он не должен выставляться за пределы этого типа, даже в рамках одного и того же проекта. Это делает вещи более безопасными и более аккуратными - когда вы используете объект, он более четко определяет, какие методы вы должны использовать.
Сказав это, я считаю разумным делать естественные частные методы для внутренних целей тестирования. Я предпочитаю использовать отражение, которое является рефакторингом - недружелюбным.
Одна вещь, которую следует учитывать, может быть суффиксом ForTest:
internal void DoThisForTest(string name)
{
DoThis(name);
}
private void DoThis(string name)
{
// Real implementation
}
Затем, когда вы используете класс внутри одного и того же проекта, очевидно (сейчас и в будущем), что вы не должны действительно использовать этот метод - он доступен только для тестовых целей. Это немного хаки, а не то, что я делаю сам, но это, по крайней мере, стоит рассмотреть.