Vérifier un appel de méthode à l'aide de Moq

142

Je suis assez nouveau dans les tests unitaires en C # et j'apprends à utiliser Moq. Voici la classe que j'essaie de tester.

class MyClass
{
    SomeClass someClass;
    public MyClass(SomeClass someClass)
    {
        this.someClass = someClass;     
    }

    public void MyMethod(string method)
    {
        method = "test"
        someClass.DoSomething(method);
    }   
}

class Someclass
{
    public DoSomething(string method)
    {
        // do something...
    }
}

Voici mon TestClass:

class MyClassTest
{
    [TestMethod()]
    public void MyMethodTest()
    {
        string action="test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();
        mockSomeClass.SetUp(a => a.DoSomething(action));
        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);
        mockSomeClass.Verify(v => v.DoSomething(It.IsAny<string>()));
    }
}

J'obtiens l'exception suivante:

Expected invocation on the mock at least once, but was never performed
No setups configured.
No invocations performed..

Je veux juste vérifier si la méthode "MyMethod" est appelée ou non. Est-ce que je manque quelque chose?

user591410
la source
1
Cela ne compilera pas s'il SomeClassn'a pas de définition pour MyMethod(string), ce qui semble ne pas l'être.
Platinum Azure
désolé..J'ai modifié ma question ..
user591410
1
Vous êtes sur la bonne voie, mais il y a des bugs dans le code affiché. Il ne compile pas - casing sur Someclass, retour nul sur DoSomething. Après cela, vous avez besoin d'un accès public, puis rendez DoSomething virtuel. En bref, vous avez probablement aussi un bogue dans votre code de production.
TrueWill
Merci pour votre réponse. Je définissais mal les arguments lors de la configuration de la méthode
fictive
"Aucune configuration configurée." Cela pourrait être trompeur. Vous n'avez pas besoin de configurer un comportement pour les méthodes qui seront appelées. Et n'oubliez pas d'exécuter la méthode "Verify" APRÈS que la méthode que vous testez devrait être appelée (donc ça va dans votre cas).
Sielu

Réponses:

209

Vous vérifiez la mauvaise méthode. Moq nécessite que vous configuriez (puis, éventuellement, vérifiez) la méthode dans la classe de dépendance.

Vous devriez faire quelque chose de plus comme ceci:

class MyClassTest
{
    [TestMethod]
    public void MyMethodTest()
    {
        string action = "test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();

        mockSomeClass.Setup(mock => mock.DoSomething());

        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);

        // Explicitly verify each expectation...
        mockSomeClass.Verify(mock => mock.DoSomething(), Times.Once());

        // ...or verify everything.
        // mockSomeClass.VerifyAll();
    }
}

En d'autres termes, vous vérifiez cet appel MyClass#MyMethod, votre classe appellera certainement SomeClass#DoSomethingune fois dans ce processus. Notez que vous n'avez pas besoin de l' Timesargument; J'étais juste en train de démontrer sa valeur.

Platine Azure
la source
Désolé, j'ai modifié ma question avec la bonne méthode. Comme vous l'avez mentionné, j'ai d'abord essayé SetUp, puis j'ai effectué la vérification. Cela me donne toujours la même exception.
user591410
22
N'est-il pas redondant de définir une attente, puis de vérifier explicitement la même attente? N'obtiendrait-il pas mockSomeClass.VerifyAll();le même résultat et ne serait-il pas plus SEC?
Tim Long
14
Oui, mais certaines personnes préfèrent être explicites.
Platinum Azure
3
Merci d'avoir au moins mentionné VerifyAll (); bien qu'évident une fois que vous y pensez. J'aurais peut-être opté pour l'approche explicite, mais beaucoup plus propre lorsque j'utilise le tout. Heureusement, les deux sont répertoriés.
JGood
1
Un inconvénient lié à Mockpar rapport à NSubstituteest que si vous essayez de vérifier également les paramètres et que la vérification échoue, cela montre simplement quelles invocations ont été effectuées, mais ne montre pas exactement ce qui était attendu si vous avez utilisé des variables dans l'expression de vérification - il affichera simplement la variable nom, pas sa valeur, vous devrez donc déboguer pour vérifier la valeur exacte de cette variable. NSubstitute affichera simplement les valeurs des deux et même là où elles étaient différentes.
Grengas le