Ich habe einen Test wie diesen:
[TestCase("~/page/myaction")]
public void Page_With_Custom_Action(string path) {
// Arrange
var pathData = new Mock<IPathData>();
var pageModel = new Mock<IPageModel>();
var repository = new Mock<IPageRepository>();
var mapper = new Mock<IControllerMapper>();
var container = new Mock<IContainer>();
container.Setup(x => x.GetInstance<IPageRepository>()).Returns(repository.Object);
repository.Setup(x => x.GetPageByUrl<IPageModel>(path)).Returns(() => pageModel.Object);
pathData.Setup(x => x.Action).Returns("myaction");
pathData.Setup(x => x.Controller).Returns("page");
var resolver = new DashboardPathResolver(pathData.Object, repository.Object, mapper.Object, container.Object);
// Act
var data = resolver.ResolvePath(path);
// Assert
Assert.NotNull(data);
Assert.AreEqual("myaction", data.Action);
Assert.AreEqual("page", data.Controller);
}
GetPageByUrl wird zweimal in meinem Dashboardpathresolver ausgeführt. Wie kann ich Moq anweisen, beim ersten Mal null und beim zweiten Mal pageModel.Ojbect zurückzugeben?
c#
unit-testing
nunit
moq
Marcus
quelle
quelle
SetupSequence()
funktioniert nicht mitCallback()
. Wenn dies nur der Fall wäre, könnte man Aufrufe der verspotteten Methode auf eine "Zustandsmaschine" -Methode überprüfen.SetupSequence
funktioniert nur für zwei Anrufe, aber was kann ich tun, wenn mehr als zwei Anrufe erforderlich sind?SetupSequence
kann für eine beliebige Anzahl von Anrufen verwendet werden. Das erste Beispiel, das ich gegeben habe, gibt eine Folge von 5 Anrufen zurück.Die vorhandenen Antworten sind großartig, aber ich dachte, ich würde meine Alternative einwerfen, die nur
System.Collections.Generic.Queue
spezielle Kenntnisse des Spott-Frameworks verwendet und keine erfordert - da ich zum Zeitpunkt des Schreibens keine hatte! :) :)Dann...
quelle
Exception
da Sie es nichtEnqueue
können. Funktioniert aberSetupSequence
(siehe Antwort von @stackunderflow zum Beispiel).Dequeue()
statt nur enthaltenDequeue
wäre, wären Sie korrekt.Das Hinzufügen eines Rückrufs hat bei mir nicht funktioniert. Stattdessen habe ich diesen Ansatz verwendet: http://haacked.com/archive/2009/09/29/moq-sequences.aspx. Am Ende hatte ich einen Test wie den folgenden:
quelle
Sie können einen Rückruf verwenden, wenn Sie Ihr Scheinobjekt einrichten. Schauen Sie sich das Beispiel aus dem Moq-Wiki an ( http://code.google.com/p/moq/wiki/QuickStart ).
Ihr Setup könnte folgendermaßen aussehen:
quelle
Setup()
Anruf erneut zu tätigen undReturn()
einen anderen Wert zu verwenden.Jetzt können Sie SetupSequence verwenden. Siehe diesen Beitrag: http://codecontracts.info/2011/07/28/moq-setupsequence-is-great-for-mocking/
quelle
Hier für die gleiche Art von Problem mit etwas anderen Anforderungen erreicht.
Ich muss verschiedene Rückgabewerte von mock erhalten, die auf unterschiedlichen Eingabewerten basieren, und eine Lösung gefunden haben, die IMO besser lesbar ist, da sie die deklarative Syntax von Moq (linq to Mocks) verwendet.
quelle
da.GetFromDb(0) == new Account { ..None.. && da.GetFromDb(1) == new Account { InActive } && ...
, überhaupt nichtIt.Is
benötigten Lambda.Die akzeptierte Antwort sowie die SetupSequence-Antwort behandeln die Rückgabe von Konstanten.
Returns()
hat einige nützliche Überladungen, bei denen Sie einen Wert zurückgeben können, der auf den Parametern basiert, die an die verspottete Methode gesendet wurden. Basierend auf der in der akzeptierten Antwort angegebenen Lösung ist hier eine weitere Erweiterungsmethode für diese Überlastungen.Leider müssen Sie für die Verwendung der Methode einige Vorlagenparameter angeben, aber das Ergebnis ist immer noch gut lesbar.
Erstellen Überlastungen für die Erweiterungsmethode mit mehreren Parametern (
T2
,T3
, usw.) , wenn nötig.quelle