Подтвердить что ты не робот

Единичное тестирование С# защищенных методов

Я из мира Java EE, но сейчас я работаю над проектом .Net. В Java, когда я хотел протестировать защищенный метод, это было довольно просто, достаточно иметь тестовый класс с тем же именем пакета.

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

Должно быть возможно сделать это без каких-либо рамок...

4b9b3361

Ответ 1

Вы можете наследовать класс, который вы тестируете в своем тестовом классе.

public class Test1 : SomeClass
{
    Asert.AreEqual(1, SomeClass.ProtectedMethod());
}

Ответ 2

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

Это не дает вам столько инкапсуляции и защиты, но довольно просто и может быть полезным.

Добавьте к AssemblyInfo.cs в сборке, содержащей внутренние методы

[assembly: InternalsVisibleTo("TestsAssembly")]

Ответ 3

Вы можете открыть защищенные методы в новом классе, который наследует класс, который вы хотите проверить.

public class ExposedClassToTest : ClassToTest
{
    public bool ExposedProtectedMethod(int parameter)
    {
        return base.ProtectedMethod(parameter);
    }
}

Ответ 4

Вы можете использовать класс PrivateObject для доступа ко всем закрытым/защищенным методам/полям.

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

Ответ 6

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

Старая ситуация:

protected class ProtectedClass{
   protected void ProtectedMethod(){
      //logic you wanted to test but can't :(
   }
}

Новая ситуация:

protected class ProtectedClass{
   private INewPublicClass _newPublicClass;

   public ProtectedClass(INewPublicClass newPublicClass) {
      _newPublicClass = newPublicClass;
   }

   protected void ProtectedMethod(){
      //the logic you wanted to test has been moved to another class
      _newPublicClass.DoStuff();
   }
}

public class NewPublicClass : INewPublicClass
{
   public void DoStuff() {
      //this logic can be tested!
   }
}

public class NewPublicClassTest
{
    NewPublicClass _target;
    public void DoStuff_WithoutInput_ShouldSucceed() {
        //Arrange test and call the method with the logic you want to test
        _target.DoStuff();
    }
}