Ist es möglich, einen out
/ ref
-Parameter mit Moq (3.0+) zuzuweisen?
Ich habe mir die Verwendung angesehen Callback()
, unterstütze jedoch Action<>
keine Ref-Parameter, da diese auf Generika basieren. Ich möchte auch vorzugsweise eine Einschränkung ( It.Is
) für die Eingabe des ref
Parameters setzen, obwohl ich dies im Rückruf tun kann.
Ich weiß, dass Rhino Mocks diese Funktionalität unterstützt, aber das Projekt, an dem ich arbeite, verwendet bereits Moq.
It.IsAny<T>()
ähnlichen Matcher (ref It.Ref<T>.IsAny
) bis hin zur Unterstützung beim Einrichten.Callback()
und.Returns()
über benutzerdefinierte Delegattypen, die mit der Methodensignatur übereinstimmen. Geschützte Methoden werden gleichermaßen unterstützt. Siehe zB meine Antwort unten .Antworten:
Moq Version 4.8 (oder höher) bietet eine deutlich verbesserte Unterstützung für By-Ref-Parameter:
Das gleiche Muster gilt für
out
Parameter.It.Ref<T>.IsAny
funktioniert auch für C # 7-in
Parameter (da sie auch by-ref sind).quelle
out
, oder?Für 'out' scheint das Folgende für mich zu funktionieren.
Ich vermute, dass Moq beim Aufrufen von Setup den Wert von 'expectedValue' überprüft und sich daran erinnert.
Denn
ref
ich suche auch nach einer Antwort.Ich fand die folgende Kurzanleitung hilfreich: https://github.com/Moq/moq4/wiki/Quickstart
quelle
Setup
BEARBEITEN : In Moq 4.10 können Sie jetzt einen Delegaten mit einem out- oder ref-Parameter direkt an die Callback-Funktion übergeben:
Sie müssen einen Delegaten definieren und instanziieren:
Für die Moq-Version vor 4.10:
Avner Kashtan bietet in seinem Blog eine Erweiterungsmethode an, mit der der out-Parameter aus einem Rückruf festgelegt werden kann: Moq-, Callbacks- und Out-Parameter: ein besonders schwieriger Randfall
Die Lösung ist sowohl elegant als auch hackig. Elegant, da es eine fließende Syntax bietet, die sich bei anderen Moq-Rückrufen wie zu Hause fühlt. Und hacky, weil es darauf beruht, einige interne Moq-APIs über Reflection aufzurufen.
Die unter dem obigen Link angegebene Erweiterungsmethode wurde für mich nicht kompiliert, daher habe ich unten eine bearbeitete Version bereitgestellt. Sie müssen für jede Anzahl von Eingabeparametern eine Signatur erstellen. Ich habe 0 und 1 angegeben, aber die weitere Erweiterung sollte einfach sein:
Mit der obigen Erweiterungsmethode können Sie eine Schnittstelle ohne Parameter testen, z.
.. mit folgendem Moq-Setup:
Bearbeiten : Um Void-Return-Methoden zu unterstützen, müssen Sie lediglich neue Überladungsmethoden hinzufügen:
Dies ermöglicht das Testen von Schnittstellen wie:
quelle
var methodCall = mock.GetType().GetProperty("Setup").GetValue(mock); mock.GetType().Assembly.GetType("Moq.MethodCall") .InvokeMember("SetCallbackResponse", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, methodCall, new[] { action });
mock.Setup(x=>x.Method(out d)).Callback(myDelegate).Returns(...);
Sie müssen einen Delegaten definieren und instanziieren:...Callback(new MyDelegate((out decimal v)=>v=12m))...;
Dies ist eine Dokumentation von der Moq-Site :
quelle
Scheint, als sei es nicht sofort möglich. Sieht so aus, als hätte jemand eine Lösung versucht
Siehe diesen Forumsbeitrag http://code.google.com/p/moq/issues/detail?id=176
diese Frage Überprüfen Sie den Wert des Referenzparameters mit Moq
quelle
Um einen Wert zusammen mit dem Einstellen des Ref-Parameters zurückzugeben, finden Sie hier einen Code:
Deklarieren Sie dann Ihren eigenen Delegaten, der mit der Signatur der zu verspottenden Methode übereinstimmt, und stellen Sie Ihre eigene Methodenimplementierung bereit.
quelle
Aufbauend auf Billy Jakes awnser habe ich eine volldynamische Mock-Methode mit einem out-Parameter erstellt. Ich poste dies hier für jeden, der es nützlich findet (wahrscheinlich nur für mich in der Zukunft).
quelle
Ich bin sicher, dass Scotts Lösung an einem Punkt funktioniert hat.
Aber es ist ein gutes Argument dafür, keine Reflexion zu verwenden, um einen Blick auf private Apis zu werfen. Es ist jetzt kaputt.
Ich konnte Parameter mit einem Delegaten festlegen
quelle
Dies kann eine Lösung sein.
quelle
Ich hatte mit vielen der Vorschläge hier zu kämpfen, bevor ich einfach eine Instanz einer neuen 'Fake'-Klasse erstellte, die jede Schnittstelle implementiert, die Sie verspotten möchten. Dann können Sie einfach den Wert des out-Parameters mit der Methode selbst festlegen.
quelle
Ich hatte heute Nachmittag eine Stunde damit zu kämpfen und konnte nirgendwo eine Antwort finden. Nachdem ich alleine damit herumgespielt hatte, konnte ich eine Lösung finden, die für mich funktionierte.
Der Schlüssel hier ist,
mock.SetupAllProperties();
der alle Eigenschaften für Sie auslöscht. Dies funktioniert möglicherweise nicht in jedem Testfallszenario, aber wenn Sie sich nur darum kümmern, dasreturn value
zu erhaltenYourMethod
, funktioniert dies einwandfrei.quelle