Sono curioso di sapere se qualcuno ha intrapreso la strada dei test di integrazione transazionale con aspnet ed ef core ? Voglio essere in grado di eseguire test di integrazione completi fino al db (non utilizzando un db in memoria). Ci sono 2 problemi:
Vorrei completare i test in una transazione ( _dbContext.Database.BeginTransactionAsync()
). Il problema è il DbContext che ottengo da:
_server = new TestServer(builder);
_services = _server.Host.Services;
_dbContext = (AppDbContext)_services.GetService(typeof(AppDbContext))
Sarà in un ambito diverso (quindi un'istanza diversa) rispetto a quello che viene risolto dal middleware AspNetCore. Quindi, solo il codice di prova sarebbe transazionale, non alcun codice eseguito dal TestServer
. Ho preso in considerazione l'utilizzo di alcuni middleware di test in una classe TestStartup
che avrebbe avvolto il codice API in una transazione, ma il problema è che verrà smaltito / ripristinato prima che il test possa valutarlo. Considera il seguente caso d'uso:
In questo caso, il test deve accedere alla stessa istanza di dbContext utilizzata dal server di test. Ho provato alcuni modi hacky per passare il contesto usando AsyncLocal
che non funzionava, quindi ho semplicemente provato ad usare un semplice membro static
. Ma anche questo non funzionava, quindi sembra che ci sia un certo isolamento AppDomain tra l'app di test e il Sono curioso di sapere se qualcuno ha percorso questa strada e, in tal caso, che cosa hanno inventato? TestServer
.
Sto solo chiudendo questo problema. La soluzione era registrare DbContext come un singleton nella classe di avvio del test. Quindi, nei test:
services.AddDbContext<HostContext>(Configure, ServiceLifetime.Singleton);
Ma, nell'applicazione, sarebbe registrato come:
services.AddDbContext<HostContext>(Configure, ServiceLifetime.Transient);
AGGIORNARE
Una risposta più completa è stata pubblicata qui http://nance.io/leveling-up-your-dotnet-testing-transactional-integration-testing-in-asp-net-core/