2009-04-08 13 views
49

Ich habe ein Mock-Objekt, das als Konstruktor-Argument an ein anderes Objekt übergeben wird.Rhino Mocks AssertWasCalled (mehrere Male) auf Eigenschaft Getter mit AAA

Wie kann ich testen, dass die Eigenschaft eines verspotteten Objekts aufgerufen wurde? Dies ist der Code Ich bin derzeit mit:

INewContactAttributes newContact = MockRepository.GenerateMock<INewContactAttributes>(); 
newContact.Stub(x => x.Forenames).Return("One Two Three"); 
someobject.ConsumeContact(newContact); 
newContact.AssertWasCalled(x => { var dummy = x.Forenames; }); 

Dies funktioniert, außer wenn sie innerhalb des „Someobject“ der Getter auf Vornamen Eigenschaft wird mehrfach verwendet. Das ist, wenn ich "Rhino.Mocks.Exceptions.ExpectationViolationException: INewContactAttributes.get_Forenames(); Erwartete # 1, # 2 .. Die tatsächliche"

einfach

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.Any()); 

mit nicht funktioniert und gibt den Fehler unten :

"Die Erwartung wurde aus der Warteerwartungsliste entfernt, haben Sie Repeat.Any() aufgerufen? Dies wird in AssertWasCalled() nicht unterstützt."

Also, wie kann ich für die Mehrfachanrufe sorgen?

+1

Klicken Sie auf die ✓ unter eine der Antworten, es zu akzeptieren. – lockstock

Antwort

70

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.AtLeastOnce());

Repeat.Any nicht mit AssertWasCalled weil 0 zählt als jede funktioniert .. Wenn sie nicht aufgerufen wurde, würde AsserWasCalled TRUE zurückgeben, auch wenn sie nicht aufgerufen wurde.

+3

Danke, das hat mir Zeit gespart. Sollte die beste Antwort auf die Frage sein (IMO) – Thies

2

Was ist Ihre Motivation hinter der Anzahl der Aufrufe? Ist es eine besonders teure Operation? Wenn dem so ist, dann würde ich vorschlagen, dass Sie es stattdessen hinter eine Methode stellen, da semantisch gesprochene Eigenschaften kostengünstige Aufrufe sein sollten.

Auch die Überprüfung, wie oft eine Eigenschaft aufgerufen wird, ist nicht die Aufgabe des Komponententests (keine Sorge, es ist ein häufiger Fehler, zu viel zu testen, wir waren alle schon dort). Was Sie wirklich testen sollten, ist, dass die Methode die erwartete Ausgabe erzeugt, wenn Sie den Status Ihres Mock-Objekts angeben. Die Häufigkeit, mit der eine Methode aufgerufen wird, spielt keine Rolle (es sei denn, es handelt sich um einen Dienst zum Senden einer E-Mail oder etwas). Es ist ein Implementierungsdetail, das Sie normalerweise nicht testen würden, da ein einfacher Refactor Ihre Tests unterbrechen würde, da sie zu spezifisch wären.

+0

Danke Garry. Ich möchte eigentlich nicht testen, wie oft der Getter aufgerufen wurde, nur dass er aufgerufen wurde. Wie es passiert, verwendet das "SomeObject" es intern zweimal. Das ist die Ursache des Problems; Es scheint keine Möglichkeit zu geben, .Repeat.Any() mit AssertWasCalled zu verwenden. – Confused

+0

Im Allgemeinen wird jedoch überprüft, ob die Ausgabe korrekt ist, ob die Eigenschaft aufgerufen wurde. Wie könnte die Ausgabe korrekt sein, wenn die Eigenschaft nicht aufgerufen wurde? –

+0

Garry, Ihre Kommentare sind gültig, aber Sie müssen auch sagen, dass es im Grunde zwei Schulen von Scheintests gibt: zustandsbasiert und interaktionsbasiert. Die Angabe, wie oft eine Methode aufgerufen wird, ist im interaktionsbasierten Testen absolut gültig. Und manchmal ändert sich der Zustand nicht. –

0

newContact.Expect (c => c.ForeNames) .Return (...) .Repeat.Any()

2

Je nach Ihrer Version von Rhino Sie verwenden, können Sie verwenden:

// Call to mock object here 
LastCall.IgnoreArguments().Repeat.Never(); 
26

ich mit chris Antwort

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.AtLeastOnce()); 

Zusätzlich stimmen Wenn Sie genau wissen, wie oft das Objekt aufgerufen werden Sie können tun

newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.Times(n)); 

wo n ist ein Int.

0

Von Here:

mock.AssertWasCalled(x => x.Name ="Bob"); 

oder

mock.AssertWasCalled(x => x.Name =Arg.Is("Bob")); 

oder

mock.AssertWasCalled(x => x.Name =Arg<string>.Is.NotNull); 
+1

Diese Antwort wird nicht funktionieren, weil Sie assert zu der Methode, die einmal aufgerufen wird, bleiben werden. Bei der Frage geht es darum zu behaupten, dass die Methode mehrfach aufgerufen wurde. – Peter