Je viens du monde Java EE mais maintenant je travaille sur un projet .Net. Dans Java quand je voulais tester une méthode protégée, c'était assez facile, il suffit d'avoir la classe de test avec le même nom de package.
Existe-t-il quelque chose de similaire pour C #? Existe-t-il une bonne pratique pour tester unitairement les méthodes protégées? Je n'ai trouvé que des frameworks et des gens disant que je ne devais tester que des méthodes publiques.
Il devrait être possible de le faire sans aucun cadre…
Vous pouvez hériter de la classe que vous testez sur votre classe de test.
public class Test1 : SomeClass
{
Asert.AreEqual(1, SomeClass.ProtectedMethod());
}
Une autre option consiste à utiliser internal
pour ces méthodes, puis à utiliser InternalsVisibleTo
pour permettre à votre assembly de test d'accéder à ces méthodes. Cela n'empêche pas les méthodes d'être consommées par d'autres classes dans le même assembly, mais cela empêche leur accès par d'autres assemblys qui ne sont pas votre assembly de test.
Cela ne vous donne pas autant d'encapsulation et de protection, mais c'est assez simple et peut être utile.
Ajouter à AssemblyInfo.cs
dans l'assemblage contenant les méthodes internes
[Assembly: InternalsVisibleTo("TestsAssembly")]
Vous pouvez exposer les méthodes protégées dans une nouvelle classe qui hérite de la classe que vous souhaitez tester.
public class ExposedClassToTest : ClassToTest
{
public bool ExposedProtectedMethod(int parameter)
{
return base.ProtectedMethod(parameter);
}
}
Vous pouvez utiliser la classe PrivateObject pour accéder à toutes les méthodes/champs privés/protégés.
PrivateObject est une classe du framework de tests unitaires Microsoft qui est un wrapper qui permet d'appeler des membres normalement inaccessibles pour les tests unitaires.
Vous pouvez utiliser la réflexion pour appeler des méthodes privées et protégées.
Voir ici pour plus:
Bien que la réponse acceptée soit la meilleure, elle n'a pas résolu mon problème. Dérivant de la classe protégée a pollué ma classe de test avec beaucoup d'autres choses. En fin de compte, j'ai choisi d'extraire la logique à tester dans une classe publique et de tester cela. Assurément, cela ne fonctionnera pas pour tout le monde et pourrait nécessiter un certain remaniement, mais si vous faites défiler jusqu'à cette réponse, cela pourrait vous aider. :) Voici un exemple
Ancienne situation:
protected class ProtectedClass{
protected void ProtectedMethod(){
//logic you wanted to test but can't :(
}
}
Nouvelle situation:
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();
}
}