web-dev-qa-db-fra.com

Comment écrire un test unitaire pour une méthode privée en c # en utilisant le framework moq?

Je veux écrire un test unitaire pour la méthode privée en C # en utilisant le framework moq, j'ai cherché dans StackOverFlow et Google, mais je ne trouve pas le résultat attendu. S'il vous plaît aidez-moi si vous le pouvez.

19
PeaceInMind

Vous ne pouvez pas, du moins pas avec Moq.

Mais plus important encore, vous ne devriez pas. Tout d'abord, vous ne testez pas méthodes, vous testez comportements. Deuxièmement, afin de tester les comportements, vous exercez l'API public d'un type et vérifiez les résultats de cet exercice.

Les méthodes privées sont des détails d'implémentation. Vous ne voulez pas vérifier comment les choses se font, vous voulez vérifier que les choses do se font.

37
dcastro

Peut-être que vous ne devriez pas (voir les autres réponses pour savoir pourquoi), mais vous pouvez le faire en utilisant Microsoft Visual Studio Test Tools . Un exemple simplifié est donné ci-dessous.

Étant donné la classe suivante que vous souhaitez tester:

public class ClassToTest
{
    private int Duplicate(int n)
    {
        return n*2;
    }
}

Vous pouvez utiliser le code suivant pour tester la méthode privée Duplicate:

using Microsoft.VisualStudio.TestTools.UnitTesting;

// ...

[TestMethod]
public void MyTestMethod()
{
    // Arrange
    var testClass = new ClassToTest();
    var privateObject = new PrivateObject(testClass);

    // Act
    var output = (int) privateObject.Invoke("Duplicate", 21);

    // Assert
    Assert.AreEqual(42, output);
}
9
Grinn

Tout simplement pas. Les méthodes privées ne sont pas visibles pour les autres classes.

Il existe plusieurs façons de contourner ce problème:

  • Traitez le privé comme faisant partie de la méthode que vous testez, couvrez-le dans leurs tests unitaires. Considérez les méthodes publiques comme des boîtes noires et testez leurs opérations.
  • Protégez-la et héritez votre classe de test de la classe que vous testez (ou utilisez une partie - même idée)
  • Rendez-le public (ce qui si vous codez sur une interface ne l'expose pas réellement à vos consommateurs)

Pour les méthodes publiques (option trois), il est possible de se moquer partiellement de la classe où vous pouvez remplacer la méthode. Dans Moq, vous pouvez faire ceci comme ceci:

var moq = new Mock<MyClass>();
moq.CallBase = true;
moq.Setup(x => x.MyPublicMethodToOverride()).Returns(true);

Il y a plus de détails ici .

6
Liath

Dans les AssemblyInfo.cs de votre projet, ajoutez

[Assembly: InternalsVisibleTo("Namespace.OfYourUnitTest.Project")]

puis vous rendez la méthode interne au lieu de privée.

Elle a l'avantage d'éviter de la rendre publique.

Cependant, comme l'a souligné dcastro, certaines personnes sont fortement en désaccord avec cette méthode de test.

6
alexandrekow