Überprüfen Sie einen Methodenaufruf mit Moq

141

Ich bin ziemlich neu in Unit-Tests in C # und lerne, Moq zu verwenden. Unten ist die Klasse, die ich zu testen versuche.

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...
    }
}

Unten ist meine Testklasse:

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>()));
    }
}

Ich bekomme folgende Ausnahme:

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

Ich möchte nur überprüfen, ob die Methode "MyMethod" aufgerufen wird oder nicht. Vermisse ich etwas

user591410
quelle
1
Das wird nicht kompiliert, wenn SomeClasses keine Definition für gibt MyMethod(string), für die es anscheinend nicht so ist.
Platinum Azure
Entschuldigung .. Ich habe meine Frage bearbeitet ..
user591410
1
Sie sind auf dem richtigen Weg, aber der veröffentlichte Code enthält Fehler. Es wird nicht kompiliert - Gehäuse für Someclass, ungültige Rückgabe für DoSomething. Danach benötigen Sie öffentlichen Zugriff und machen DoSomething virtuell. Kurz gesagt, Sie haben wahrscheinlich auch einen Fehler in Ihrem Produktionscode.
TrueWill
Vielen Dank für Ihre Antwort. Ich habe die Argumente falsch eingestellt, als ich die Mock-Methode eingerichtet habe.
user591410
"Keine Setups konfiguriert." Könnte irreführend sein. Sie müssen kein Verhalten für Methoden einrichten, die aufgerufen werden. Denken Sie auch daran, die Methode "Verify" auszuführen, nachdem die Methode, die Sie testen, aufgerufen werden soll (in Ihrem Fall ist dies also in Ordnung).
Sielu

Antworten:

207

Sie überprüfen die falsche Methode. Moq erfordert, dass Sie die Methode in der Abhängigkeitsklasse einrichten (und dann optional überprüfen).

Sie sollten etwas Ähnliches tun:

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();
    }
}

Mit anderen Worten, Sie überprüfen, dass MyClass#MyMethodIhre Klasse SomeClass#DoSomethingin diesem Prozess definitiv einmal anruft . Beachten Sie, dass Sie das TimesArgument nicht benötigen . Ich habe nur seinen Wert demonstriert.

Platinum Azure
quelle
Entschuldigung, ich habe meine Frage mit der richtigen Methode bearbeitet. Wie Sie bereits erwähnt haben, habe ich zuerst SetUp ausprobiert und dann Verify ausgeführt. Es gibt mir immer noch die gleiche Ausnahme.
user591410
22
Ist es nicht redundant, eine Erwartung einzurichten und diese dann explizit zu überprüfen? Würden Sie nicht mockSomeClass.VerifyAll();das gleiche Ergebnis erzielen und trockener sein?
Tim Long
13
Ja, aber einige Leute bevorzugen es, explizit zu sein.
Platinum Azure
3
Vielen Dank, dass Sie zumindest VerifyAll () erwähnt haben. während offensichtlich, wenn Sie darüber nachdenken. Ich hätte mich vielleicht für den expliziten Ansatz entschieden, aber viel sauberer, wenn ich das All benutze. Dankbar sind beide aufgelistet.
JGood
1
Ein verwandter Nachteil von im MockVergleich zu NSubstituteist, dass, wenn Sie versuchen, auch die Parameter zu überprüfen und die Überprüfung fehlschlägt, nur angezeigt wird, welche Aufrufe ausgeführt wurden, aber nicht, was genau erwartet wurde, wenn Sie Variablen im Überprüfungsausdruck verwendet haben - es wird nur Variable angezeigt Name, nicht sein Wert, daher müssen Sie debuggen, um zu überprüfen, welchen Wert genau diese Variable hat. NSubstitute zeigt nur Werte von beiden und sogar dort, wo es anders war.
Grengas