Come posso dire a Moq di restituire un compito?

Ho un’interfaccia che dichiara

Task DoSomethingAsync(); 

Sto usando MoqFramework per i miei test:

 [TestMethod()] public async Task MyAsyncTest() { Mock mock = new Mock(); mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => {  }); ... } 

Poi nel mio test eseguo il codice che invoca await DoSomethingAsync() . E il test fallisce proprio su quella linea. Che cosa sto facendo di sbagliato?

Il tuo metodo non ha callback quindi non c’è motivo di usare .CallBack() . Puoi semplicemente restituire un’attività con i valori desiderati usando .Returns() e Task.FromResult , ad esempio:

 MyType someValue=...; mock.Setup(arg=>arg.DoSomethingAsync()) .Returns(Task.FromResult(someValue)); 

Aggiornamento 2014-06-22

Moq 4.2 ha due nuovi metodi di estensione per aiutare con questo.

 mock.Setup(arg=>arg.DoSomethingAsync()) .ReturnsAsync(someValue); mock.Setup(arg=>arg.DoSomethingAsync()) .ThrowsAsync(new InvalidOperationException()); 

Aggiornamento 2016-05-05

Poiché Seth Flowers menziona nell’altra risposta , ReturnsAsync è disponibile solo per i metodi che restituiscono un’attività Task . Per i metodi che restituiscono solo un’attività,

 .Returns(Task.FromResult(default(object))) 

può essere utilizzata.

Come mostrato in questa risposta , in .NET 4.6 questo è semplificato in .Returns(Task.CompletedTask); , per esempio:

 mock.Setup(arg=>arg.DoSomethingAsync()) .Returns(Task.CompletedTask); 

Problema simile

Ho un’interfaccia simile a quella di:

 Task DoSomething(int arg); 

Sintomi

Il mio test dell’unità è fallito quando il mio servizio in prova ha awaited la chiamata a DoSomething .

fissare

A differenza della risposta accettata, non è ansible richiamare .ReturnsAsync() sul proprio Setup() di questo metodo in questo scenario, poiché il metodo restituisce l’attività non generica anziché l’ Task .

Tuttavia, si è ancora in grado di utilizzare .Returns(Task.FromResult(default(object))) sul setup, consentendo il passaggio del test.

Hai solo bisogno di aggiungere .Returns(Task.FromResult(0)); dopo il callback.

Esempio:

 mock.Setup(arg => arg.DoSomethingAsync()) .Callback(() => {  }) .Returns(Task.FromResult(0)); 

Ora puoi anche utilizzare il pacchetto Talentsoft.Moq.SetupAsync https://github.com/TalentSoft/Moq.SetupAsync

Che sulla base delle risposte trovate qui e delle idee proposte a Moq ma ancora non ancora implementate qui: https://github.com/moq/moq4/issues/384 , semplifica enormemente l’impostazione dei metodi asincroni

Alcuni esempi trovati nelle risposte precedenti fatte con l’estensione SetupAsync:

 mock.SetupAsync(arg=>arg.DoSomethingAsync()); mock.SetupAsync(arg=>arg.DoSomethingAsync()).Callback(() => {  }); mock.SetupAsync(arg=>arg.DoSomethingAsync()).Throws(new InvalidOperationException());