Sto cercando di creare un repository di test usando Moq con EF Core, usando i suoi metodi asincroni (come AddAsync
e SaveChangesAsync
), ma non ho avuto il minimo successo ...
Ho trovato molti e molti post del blog (comprese le domande qui), ma niente funziona per me.
Ad esempio, ho letteralmente copiato il codice da questo articolo e ho cercato di implementare i suoi riferimenti: [ https://fpnotebook.wordpress.com/2017/05/29/asp-net-core-testing-repositories-and-mocking-ef /] ma il problema è sempre lo stesso, ad esempio:
Messaggio: Moq.MockException:
Invocazione prevista sul mock una volta, ma era 0 volte: m => m.AddAsync (It.IsAny (),)
Nessuna configurazione configurata.
E lo stesso vale per SaveChangesAsync
.
Ecco un codice di esempio che ho cercato di implementare:
// La configurazione
dbSetMock.Setup(m => m.AddAsync(It.IsAny<T>), It.IsAny<CancellationToken>()))
.Callback ((T model, CancellationToken token) => {queryableList.Concat (new [] {model})}})
.Returns ((T model, CancellationToken token) => Task.FromResult((EntityEntry<T>) null));
// Il test stesso
[Fact]
public async void AddAsyncTest ()
{
var mockSet = new Mock <DbSet <Wine >> ();
var mockContext = new Mock <SQLContext> (_ options);
mockContext.Setup (m => m.Set <Wine> ()). Returns (mockSet.Object);
var service = new WineCommandRepository (mockContext.Object);
await service.Insert (new Wine
{
IdWine = 1,
Name = "Wine1"
});
mockContext.Object.SaveChanges ();
mockSet.Verify (m => m.AddAsync (It.IsAny <Wine>),
new CancellationToken ()), Times.Once ());
mockContext.Verify (m => m.SaveChanges (), Times.Once ());
}
Non c'è niente di straordinario nel mio codice, ho usato quello che ho sempre usato per il repository sincrono, ma questo caso è nuovo per me.
Qualcuno ha superato questo e ha qualche esempio o raccomandazione da condividere?
Sospetto che il motivo per cui questo non funzioni è che questo controllo (per il quale ho aggiunto parentesi mancanti dalla domanda e rimosso parentesi non necessarie) non passerà mai:
mockSet.Verify(m => m.AddAsync(It.IsAny<Wine>()), new CancellationToken()), Times.Once);
Il motivo è che Verify
sta verificando che il metodo è stato chiamato con i parametri forniti, non qualcosa di "equivalente", ma esattamente quello che gli hai detto (il riferimento è uguale). Tuttavia, a Verify
viene assegnata una nuova istanza di CancellationToken e non è possibile che il codice in prova restituisca l'esatta istanza di un CancellationToken.
O è necessario utilizzare It.IsAny<CancellationToken>()
, oppure se si estrae il codice da testare in modo esplicito utilizzando new CancellationToken()
e lo si fornisce tramite l'impostazione di test, quindi è possibile fornire tale istanza specifica a Verify
.
Mentre sono qui, dovrei offrire It.IsAny
per l'utilizzo di It.IsAny
nel caso non lo sapessi. Dai un'occhiata alla risposta e ai commenti non accettati di questa domanda , quindi alla risposta accettata.