Sequenza di chiamata del metodo MOQ

Sto prendendo in giro un wrapper che usiamo per alcune chiamate alle librerie aziendali. Tutto andava bene nel mondo, i miei test sono passati e il codice vero funzionava!

Tuttavia, ho quindi esteso la funzionalità e verificato che tutti i test siano ancora passati. Bingo – lo hanno fatto. Tuttavia non lo hanno fatto nel mondo reale perché c’è un’aspettativa

InitialiseDBCommand(string, commandtype) 

sarà chiamato prima

 AddCmdParameter(string, dbtype, object) 

Quindi, come un bravo ragazzo, la prima cosa che voglio fare è scrivere un test che mostri questo comportamento e si aspetti che venga lanciata un’eccezione.

Quello di cui ho bisogno è di montare AddCmmParater per generare un’eccezione. IF InitialDBCommand non è stato chiamato con nessuna stringa.

Immagino di poterlo fare con una richiamata, ma sembra che il moq’ing di una sequenza di chiamata del metodo (non una sequenza di ritorno del metodo) debba essere lì.

Qualcosa di simile a

 iDataAccessHelper.Setup(s=>s.AddCmdOutputParameter(It.IsAny(), It.IsAny(), It.IsAny())) .When(w=>w.InitialiseDBCommand(etc etc) .Throws() 

Qualche indicazione?

Beh, se vuoi semplicemente testare se 2 metodi sono chiamati nell’ordine corretto, un modo per farlo sarebbe quello di aggiungere un contatore che viene incrementato ogni volta che uno dei metodi viene chiamato e quindi controllare se è il numero corretto. Ecco una risposta che la descrive. Ecco come lo scriverei per il tuo scenario:

 [Test] public void TestingCallOrder() { int counter = 0; var mockDataAccessStuff = new Mock(); mockDataAccessStuff.Setup(x => x.AddCmdParameter(It.IsAny())).Callback(() => { Assert.AreEqual(counter, 0); counter++; }); mockDataAccessStuff.Setup(x => x.InitialiseDbCommand(It.IsAny())).Callback(() => { Assert.AreEqual(counter, 1); counter++; }); // more of the same var myClass = new ClassThatImTesting(mockDataAccessStuff.Object); myClass.DoWork(); // make sure both methods are called at least once ... mockDataAccessStuff.Verify(x => x.AddCmdParameter(It.IsAny()), Times.Once()); mockDataAccessStuff.Verify(x => x.InitialiseDbCommand(It.IsAny()), Times.Once()); } 

Penso che sia un modo molto pulito e leggibile per scrivere il test.

Esiste una libreria che estende Moq per aggiungere questa funzionalità chiamata Sequenze Moq . Che dai loro esempi assomiglia

 using (Sequence.Create()) { mock.Setup(_ => _.Method1()).InSequence(); mock.Setup(_ => _.Method2()).InSequence(Times.AtMostOnce()); ... // Logic that triggers the above method calls should be done here. ... }"; 

Asserisce che Method1 viene chiamato prima di Method2