Gegeben die folgende Schnittstelle:
public interface IFoo
{
bool Foo(string a, bool b = false);
}
Der Versuch, es mit Moq zu verspotten:
var mock = new Mock<IFoo>();
mock.Setup(mock => mock.Foo(It.IsAny<string>())).Returns(false);
gibt beim Kompilieren den folgenden Fehler aus:
Ein Ausdrucksbaum darf keinen Aufruf oder Aufruf enthalten, der optionale Argumente verwendet
Ich habe das oben erwähnte Problem als Erweiterung in der Liste der Probleme von Moq gefunden und es scheint der Version 4.5 zugewiesen zu sein (wann immer dies der Fall ist).
Meine Frage ist: Was soll ich tun, da das oben genannte Problem nicht in Kürze behoben wird? Sind meine Optionen nur, entweder den Standardwert des optionalen Parameters jedes Mal explizit festzulegen, wenn ich ihn verspotte (was den Punkt der Angabe eines Punktes überhaupt zunichte macht) oder eine Überladung ohne den Bool zu erzeugen (wie ich es getan hätte) vor C # 4)?
Oder hat jemand einen klügeren Weg gefunden, um dieses Problem zu lösen?
quelle
Antworten:
Ich glaube, Ihre einzige Wahl im Moment ist es, den
bool
Parameter explizit in das Setup für aufzunehmenFoo
.Ich denke nicht, dass es den Zweck der Angabe eines Standardwerts zunichte macht. Der Standardwert ist eine Annehmlichkeit für das Aufrufen von Code, aber ich denke, dass Sie in Ihren Tests explizit sein sollten. Angenommen, Sie könnten die Angabe des
bool
Parameters weglassen. Was passiert, wenn in Zukunft jemand den Standardwert vonb
in änderttrue
? Dies führt zu fehlgeschlagenen Tests (und das zu Recht), die jedoch aufgrund der versteckten Annahme schwieriger zu behebenb
sindfalse
. Die explizite Angabe desbool
Parameters hat einen weiteren Vorteil: Sie verbessert die Lesbarkeit Ihrer Tests. Jemand, der sie durchläuft, wird schnell wissen, dass es eineFoo
Funktion gibt, die zwei Parameter akzeptiert. Das sind zumindest meine 2 Cent :)Wenn Sie es jedes Mal angeben, wenn Sie es verspotten, duplizieren Sie keinen Code: Erstellen und / oder initialisieren Sie das Modell in einer Funktion, sodass Sie nur einen einzigen Änderungspunkt haben. Wenn Sie wirklich wollen, können Sie das offensichtliche Manko von Moq hier überwinden, indem Sie
Foo
die Parameter in diese Initialisierungsfunktion duplizieren :quelle
if (!x) {} else {}
Anti-Muster :)Moq ist heute auf dieses Problem gestoßen und unterstützt diesen Anwendungsfall nicht. Es scheint also, dass das Überschreiben der Methode für diesen Fall ausreichend wäre.
Jetzt sind beide Methoden verfügbar und dieses Beispiel würde funktionieren:
quelle
Mit Moq Version 4.10.1 konnte ich Folgendes tun
Mit Schnittstelle:
Und verspotten
Löst einen Aufruf von Foo mit dem ersten Parameter in Ordnung auf
quelle