2009-04-08 8 views
49

J'ai un objet mocké qui est passé en tant qu'argument de constructeur à un autre objet.Rhino Mocks AssertWasCalled (plusieurs fois) sur le getter de propriété utilisant AAA

Comment puis-je tester que la propriété d'un objet mocké a été appelée? Ceci est du code Je suis actuellement en utilisant:

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

Cela fonctionne, sauf si dans le « SomeObject » le getter sur la propriété est utilisé plusieurs prénoms fois. C'est quand je reçois "Rhino.Mocks.Exceptions.ExpectationViolationException: INewContactAttributes.get_Forenames(); # attendu 1, 2 .. # réelle"

simplement en utilisant

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

ne fonctionne pas et donne l'erreur ci-dessous :

"L'attente a été supprimée de la liste des attentes en attente, avez-vous appelé Repeat.Any()? Cela n'est pas pris en charge dans AssertWasCalled()."

Alors, comment répondre aux appels multiples?

+1

Cliquez sur le ✓ ci-dessous l'une des réponses à l'accepter. – lockstock

Répondre

70

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

Repeat.Any ne fonctionne pas avec AssertWasCalled parce que 0 compte comme tout .. Donc, s'il n'était pas appelé, le AsserWasCalled retournera TRUE même s'il n'a pas été appelé.

+3

Merci, cela m'a fait gagner du temps. Devrait être la meilleure réponse à la question (IMO) – Thies

2

Quelle est votre motivation pour vérifier le nombre de fois où il est appelé? Est-ce une opération particulièrement coûteuse? Si oui, alors je suggérerais que vous mettiez derrière une méthode à la place car, sémantiquement parlant, les propriétés devraient être des appels peu coûteux.

En outre, vérifier le nombre de fois qu'une propriété est appelée n'est pas la poussée des tests unitaires (ne vous inquiétez pas c'est une erreur commune de trop tester, nous avons tous été là). Qu'est-ce que vous devriez vraiment tester est que, compte tenu de l'état de votre objet fictif que la méthode produit la sortie attendue. Le nombre de fois qu'une méthode est appelée à faire cela n'a pas vraiment d'importance (à moins que ce soit un service pour envoyer un email ou autre). Il s'agit d'un détail de mise en œuvre que vous ne testeriez normalement pas car un simple refactor pourrait casser vos tests car ils seraient trop spécifiques.

+0

Merci Garry. En fait, je ne veux pas tester combien de fois le getter a été appelé, simplement qu'il a été appelé. En l'occurrence, "someobject" l'utilise deux fois en interne. C'est la cause du problème; il semble y avoir aucun moyen d'utiliser .Repeat.Any() avec le AssertWasCalled. – Confused

+0

Mais généralement vérifier que la sortie est correcte vérifie que la propriété a été appelée. Comment la sortie peut-elle être correcte si la propriété n'a pas été appelée? –

+0

Garry, vos commentaires sont valides, mais vous devez également dire qu'il y a essentiellement deux écoles de tests simulés: basée sur l'état et basée sur l'interaction. L'affirmation du nombre de fois qu'une méthode est appelée est parfaitement valide dans les tests basés sur l'interaction. Et parfois l'état ne change pas. –

0

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

2

En fonction de votre version de Rhino que vous utilisez, vous pouvez utiliser:

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

Je suis d'accord avec chris réponse

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

De plus, si vous savez exactement combien de fois la propriété serait appelé vous pouvez le faire

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

où n est un int.

0

De Here:

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

ou

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

ou

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

Cette réponse ne fonctionnera pas, parce que vous affirmerez toujours à la méthode étant appelée une fois. La question consiste à affirmer que la méthode a été appelée plusieurs fois. – Peter