2009-07-29 13 views
24

il mio team ha recentemente preso la decisione di utilizzare Moq come framework di simulazione per la sua straordinaria flessibilità e sintassi altamente leggibile. Dato che siamo nuovi, sto inciampando in quelle che sembrano essere semplici domande - le ricerche (qui, Google, ecc.) Trovano molte discussioni su altre sfumature di Moq, ma non necessariamente ciò che cerco, e le poche domande apparentemente collegate si sono trasformate in false piste.Metodi void "cortocircuiti" con Moq?

Stiamo testando una classe che ha una dipendenza esterna (Amazon SimpleDb per essere precisi) ma non vogliamo che i nostri test vincolino ad avere una connessione live. Un particolare metodo:

  • applica una logica "business"
  • Se del caso, invoca una chiamata fuori per SDB tramite un provider che abbiamo costruito, chiamiamolo SaveItem()

voglio unità testare questo in modo tale da configurare il contesto richiesto e assicurare che SaveItem() sia stato richiamato, ma in modo che SaveItem() non sia realmente invocato (perché A) il provider di SDB è un mock che non è completamente idratato e probabilmente bomba e B) Non voglio dover pagare per quella transazione centinaia e migliaia di volte).

Quando si trattava di metodi che restituivano un valore, ciò era banale.

mockDb.Setup(d => d.GiveMeSomething()).Returns("Foo"); 

Nel caso che io schema di cui sopra, però, il mio metodo "SaveItem()" è nullo e quindi la possibilità di utilizzare il metodo di Moq Returns() non è disponibile. E mentre posso impostare una richiamata per verificare che venga invocato il numero SaveItem(), non riesco comunque a convincerlo a non fare nulla.

Naive/speranzoso, ho pensato che il seguente avrebbe funzionato, ma sembra richiamare ancora il metodo:

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())); 

Quindi la domanda da un milione di dollari: Qual è il Moq del seguente codice fittizio?

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())).STOP_RIGHT_HERE(); 
+0

modificato per chiarire la situazione, il test è per una classe "business" in giro, non per l'effettiva attuazione SimpleDB. L'implementazione di SimpleDB è stata testata altrove, qui, è quello che sto prendendo in giro. – bakasan

risposta

29

Se il metodo SaveItem() è virtuale o astratta, e non si sta impostando Callbase = true, allora il metodo dovrebbe essere re-implementate per non fare nulla per il mock.

Si dovrebbe essere in grado di fare:

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())).Verifiable(); 

... test here ... 

mockDb.Verify(); 
+0

Perfetto! Assolutamente non avevo idea che fosse l'intenzione della roba Verifiable()/Verify(), e senza una documentazione più formale, non avrei nemmeno saputo leggere su thread e post in quell'area. Ho appena dato un vortice e ora ho sia casi di test positivi che negativi contro questo scenario. Grazie mille! – bakasan

+2

+1; Inoltre, puoi verificare tutte le tue chiamate indipendentemente dal flag Verificabile() chiamando mockDb.VerifyAll() –

+0

Possibile che questa risposta sia espansa per l'altro scenario il metodo i.e non è né virtuale né astratto? – leon