Rhino prende in giro AssertWasCalled (più volte) sul getter di proprietà utilizzando AAA
-
05-09-2019 - |
Domanda
Ho un oggetto deriso che viene passato come argomento del costruttore a un altro oggetto.
Come posso verificare che la proprietà di un oggetto deriso sia stata chiamata?Questo è il codice che sto usando attualmente:
INewContactAttributes newContact = MockRepository.GenerateMock<INewContactAttributes>();
newContact.Stub(x => x.Forenames).Return("One Two Three");
someobject.ConsumeContact(newContact);
newContact.AssertWasCalled(x => { var dummy = x.Forenames; });
Funziona tranne quando all'interno di "someobject" il getter sulla proprietà Forenames viene utilizzato più volte.È allora che ottengo "Rhino.Mocks.Exceptions.ExpectationViolationException:INewContactAttributes.get_Forenames();Previsto n. 1, effettivo n. 2.."
Semplicemente usando
newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.Any());
non funziona e restituisce l'errore seguente:
"L'aspettativa è stata rimossa dall'elenco delle aspettative di attesa, hai chiamato Repeat.Any() ?Questo non è supportato in AssertWasCalled()."
Allora come posso soddisfare le molteplici chiamate?
Soluzione
newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.AtLeastOnce());
Repeat.Any
non funziona con AssertWasCalled
perché 0 conta come qualsiasi ... quindi se non è stato chiamato, il AsserWasCalled
sarebbero tornati TRUE anche se non è stato chiamato.
Altri suggerimenti
Sono d'accordo con la risposta di Chris
newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.AtLeastOnce());
Inoltre, se sai esattamente quante volte la proprietà verrà chiamata, puoi farlo
newContact.AssertWasCalled(x => { var dummy = x.Forenames; }, options => options.Repeat.Times(n));
dove n è un intero.
Qual è la tua motivazione dietro controllando il numero di volte che si chiama? Si tratta di un'operazione particolarmente costosa? Se è così, vorrei suggerire che si mette dietro un metodo, invece, come, semanticamente parlando, proprietà devono essere chiamate a basso costo.
Inoltre, controllando il numero di volte che una proprietà è chiamata non è la spinta di unit testing (non preoccupatevi è un errore comune per testare troppo, siamo stati tutti lì). Che cosa si dovrebbe davvero essere il test è che, dato lo stato del vostro oggetto finta che il metodo produce l'output previsto. Il numero di volte che un metodo è chiamato a fare che in realtà non importa (a meno che non si tratta di un servizio per inviare una e-mail o qualcosa del genere). Si tratta di un dettaglio di implementazione che normalmente non provare come un semplice refactoring sarebbe rompere il vostro test come sarebbero troppo specifici.
A seconda della versione di Rhino che si sta utilizzando, è possibile utilizzare:
// Call to mock object here
LastCall.IgnoreArguments().Repeat.Never();
newContact.Expect (c => c.ForeNames) .Return (...) .Repeat.Any ()
Qui :
mock.AssertWasCalled(x => x.Name ="Bob");
o
mock.AssertWasCalled(x => x.Name =Arg.Is("Bob"));
o
mock.AssertWasCalled(x => x.Name =Arg<string>.Is.NotNull);