C # «внутренний» модификатор доступа при выполнении юнит-тестирования - PullRequest
382 голосов
/ 11 декабря 2008

Я новичок в модульном тестировании и пытаюсь понять, стоит ли мне начинать использовать больше «внутреннего» модификатора доступа. Я знаю, что если мы используем 'internal' и устанавливаем переменную сборки 'InternalsVisibleTo', мы можем тестировать функции, которые не хотим объявлять public из проекта тестирования. Это заставляет меня думать, что я должен всегда использовать «внутренний», потому что, по крайней мере, у каждого проекта (должен?) Есть свой собственный проект тестирования. Ребята, вы можете сказать мне причину, почему я не должен этого делать? Когда я должен использовать «личное»?

Ответы [ 5 ]

1060 голосов
/ 27 ноября 2009

Внутренние классы должны быть протестированы и есть атрибут сборки:

using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("MyTests")]

Добавьте это в файл информации о проекте, например, Properties\AssemblyInfo.cs.

113 голосов
/ 11 декабря 2008

Если вы хотите протестировать частные методы, взгляните на PrivateObject и PrivateType в пространстве имен Microsoft.VisualStudio.TestTools.UnitTesting. Они предлагают простые в использовании обертки вокруг необходимого кода отражения.

Docs: PrivateType , PrivateObject

10 голосов
/ 11 декабря 2008

Продолжайте использовать приват по умолчанию. Если член не должен быть представлен вне этого типа, он не должен быть представлен вне этого типа, даже внутри одного и того же проекта. Это делает вещи более безопасными и аккуратными - когда вы используете объект, становится понятнее, какие методы вы должны использовать.

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

Одна вещь, на которую следует обратить внимание, это суффикс ForTest:

internal void DoThisForTest(string name)
{
    DoThis(name);
}

private void DoThis(string name)
{
    // Real implementation
}

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

10 голосов
/ 11 декабря 2008

Вы также можете использовать private и вызывать private методы с отражением. Если вы используете Visual Studio Team Suite, у него есть приятная функциональность, которая генерирует прокси для вызова ваших личных методов. Вот статья проекта кода, которая демонстрирует, как вы можете выполнить работу самостоятельно для модульного тестирования закрытых и защищенных методов:

http://www.codeproject.com/KB/cs/testnonpublicmembers.aspx

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

1 голос
/ 27 апреля 2019

Добавляя к ответу Эрика, вы также можете настроить это в файле 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>

См .: https://stackoverflow.com/a/49978185/1678053

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