Stellen Sie sich diese Klasse vor
public class Foo {
private Handler _h;
public Foo(Handler h)
{
_h = h;
}
public void Bar(int i)
{
_h.AsyncHandle(CalcOn(i));
}
private SomeResponse CalcOn(int i)
{
...;
}
}
Mo (q) cking Handler in einem Test von Foo, wie könnte ich überprüfen, was Bar()
passiert ist _h.AsyncHandle
?
Antworten:
Sie können die Mock.Callback-Methode verwenden:
Wenn Sie nur etwas Einfaches an dem übergebenen Argument überprüfen möchten, können Sie dies auch direkt tun:
quelle
Callback<>()
Moq-Methode angeben . Wenn Ihre Methode beispielsweise die Definition hätteHandler.AnsyncHandle(string, SomeResponse)
, würden Sie benötigen/* ... */.Callback<string, SomeResponse>(r => result = r);
. Ich habe dies an vielen Stellen nicht explizit angegeben, daher dachte ich, ich würde es hier hinzufügen./* ... */.Callback<string, SomeResponse>((s1, s2) => { str1 = s1; result = s2});
.Callback((string s1, SomeResponse s2) => /* stuff */ )
Capture.In
Helfer aufzunehmen?Gamlors Antwort funktionierte für mich, aber ich dachte, ich würde John Carpenters Kommentar erweitern, weil ich nach einer Lösung suchte, die mehr als einen Parameter umfasste. Ich nahm an, dass andere Leute, die auf diese Seite stolpern, sich in einer ähnlichen Situation befinden könnten. Ich habe diese Informationen in der Moq-Dokumentation gefunden .
Ich werde Gamlors Beispiel verwenden, aber tun wir so, als ob die AsyncHandle-Methode zwei Argumente akzeptiert: a
string
und einSomeResponse
Objekt.Grundsätzlich müssen Sie nur
It.IsAny<>()
einen weiteren Typ mit dem entsprechenden Typ hinzufügen, derCallback
Methode einen weiteren Typ hinzufügen und den Lambda-Ausdruck entsprechend ändern.quelle
Die Callback-Methode wird sicherlich funktionieren, aber wenn Sie dies mit einer Methode mit vielen Parametern tun, kann sie etwas ausführlich sein. Hier ist etwas, mit dem ich einen Teil der Kesselplatte entfernt habe.
Hier ist die Quelle für ArgumentCaptor:
quelle
Gamlors Antwort funktioniert, aber eine andere Möglichkeit (und eine, die ich im Test als aussagekräftiger betrachte) ist ...
Verify ist sehr leistungsfähig und es lohnt sich, sich daran zu gewöhnen.
quelle
Die Alternative ist auch die Verwendung der
Capture.In
Funktion desmoq
. Es ist die OOTB-moq
Funktion, die die Erfassung von Argumenten in der Sammlung ermöglicht.quelle
Callback
IMO. Da Sie Capture direkt in der Parameterliste verwenden, ist es weitaus weniger anfällig für Probleme beim Umgestalten der Parameterliste einer Methode und macht Tests daher weniger spröde. Bei Callback müssen Sie die im Setup übergebenen Parameter mit den für Callback verwendeten Typparametern synchron halten, und dies hat mir in der Vergangenheit definitiv Probleme bereitet.Sie könnten
It.Is<TValue>()
Matcher verwenden.quelle
Das funktioniert auch:
quelle
Viele gute Antworten hier! Verwenden Sie den sofort einsatzbereiten Moq-Funktionsumfang, bis Sie Aussagen zu mehreren Klassenparametern treffen müssen, die an Ihre Abhängigkeiten übergeben werden. Wenn Sie jedoch in dieser Situation enden, kann die Moq Verify-Funktion mit It.Is-Matchern den Testfehler nicht gut isolieren, und die Methode Returns / Callback zum Erfassen von Argumenten fügt Ihrem Test unnötige Codezeilen hinzu (und lange Tests sind für mich ein No-Go).
Hier ist ein Kern: https://gist.github.com/Jacob-McKay/8b8d41ebb9565f5fca23654fd944ac6b mit einer Moq (4.12) -Erweiterung, die ich geschrieben habe und die eine aussagekräftigere Möglichkeit bietet, Aussagen über Argumente zu machen, die an Mocks weitergegeben wurden, ohne die oben genannten Nachteile. So sieht der Abschnitt "Überprüfen" jetzt aus:
Ich wäre begeistert, wenn Moq eine Funktion bereitstellen würde, die dasselbe erreicht, gleichzeitig deklarativ ist und die Fehlerisolation bietet, die dies bewirkt. Daumen drücken!
quelle