Ответ 1
Вы можете наследовать класс, который вы тестируете в своем тестовом классе.
public class Test1 : SomeClass
{
Asert.AreEqual(1, SomeClass.ProtectedMethod());
}
Я из мира Java EE, но сейчас я работаю над проектом .Net. В Java, когда я хотел протестировать защищенный метод, это было довольно просто, достаточно иметь тестовый класс с тем же именем пакета.
Есть ли что-нибудь подобное для С#? Есть ли хорошая практика для модульного тестирования защищенных методов? Я нашел только фреймворки и люди говорили, что я должен тестировать только публичные методы.
Должно быть возможно сделать это без каких-либо рамок...
Вы можете наследовать класс, который вы тестируете в своем тестовом классе.
public class Test1 : SomeClass
{
Asert.AreEqual(1, SomeClass.ProtectedMethod());
}
Другой вариант - использовать internal
для этих методов, а затем использовать InternalsVisibleTo
, чтобы разрешить вашей тестовой сборке получить доступ к этим методам. Это не останавливает методы, используемые другими классами в той же сборке, но останавливает доступ к ним других сборок, которые не являются вашей тестовой сборкой.
Это не дает вам столько инкапсуляции и защиты, но довольно просто и может быть полезным.
Добавьте к AssemblyInfo.cs
в сборке, содержащей внутренние методы
[assembly: InternalsVisibleTo("TestsAssembly")]
Вы можете открыть защищенные методы в новом классе, который наследует класс, который вы хотите проверить.
public class ExposedClassToTest : ClassToTest
{
public bool ExposedProtectedMethod(int parameter)
{
return base.ProtectedMethod(parameter);
}
}
Вы можете использовать класс PrivateObject для доступа ко всем закрытым/защищенным методам/полям.
PrivateObject - это класс в структуре модульного тестирования Microsoft, который является оберткой, которая позволяет вызывать обычно недоступных членов для модульного тестирования.
Вы можете использовать отражение для вызова частных и защищенных методов.
Подробнее см. здесь:
Хотя принятый ответ является лучшим, он не решил мою проблему. Вывод из защищенного класса загрязнил мой тестовый класс многими другими вещами. В конце концов я решил извлечь логику для тестирования в открытый класс и протестировать ее. Конечно, это не будет работать для всех и может потребовать некоторого рефакторинга, но если вы прокрутили весь ответ до этого, это может просто помочь вам. :) Вот пример
Старая ситуация:
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();
}
}