A causa delle potenziali differenze tra Linq-to-Entities (EF4) e Linq-to-Objects, è necessario utilizzare un database effettivo per verificare che le mie classi di query recuperino i dati da EF correttamente. Sql CE 4 sembra essere lo strumento perfetto per questo, ma mi sono imbattuto in qualche singhiozzo. Questi test utilizzano MsTest.Come utilizzare i database Sql CE 4 per i test funzionali
Il problema che ho è se il database non viene ricreato (a causa di modifiche al modello), i dati continuano ad essere aggiunti al database dopo ogni test senza nulla togliere i dati. Ciò può potenzialmente causare conflitti nei test, con più dati restituiti da query del previsto.
La mia prima idea era di inizializzare un TransactionScope
nel metodo TestInitialize
e smaltire la transazione in TestCleanup
. Sfortunatamente, Sql CE4 non supporta le transazioni.
La mia prossima idea era quella di eliminare il database in TestCleanup
tramite una chiamata File.Delete()
. Sfortunatamente, questo sembra non funzionare dopo l'esecuzione del primo test, poiché il primo test TestCleanup
sembra cancellare il database, ma ogni test dopo il primo non sembra ricreare il database e quindi dà un errore al database il file non è stato trovato
Ho tentato di cambiare TestInitialize
e TestCleanup
tag per ClassInitialize
e ClassCleanup
per la mia classe di test, ma che con errori con un NullReferenceException
causa del test di corrente prima di ClassInitialize
(o almeno così sembra. ClassInitialize
è nella classe base in modo forse è causandolo).
Ho esaurito i modi per utilizzare efficacemente Sql CE4 per il test. Qualcuno ha qualche idea migliore?
Modifica: Ho finito per capire una soluzione. Nella mia classe di base di test dell'unità EF, avvio una nuova istanza del mio contesto dati e quindi chiamo
context.Database.Delete()
e
context.Database.Create()
. Le unit test eseguiti un po 'più lento, ma ora posso unit test in modo efficace utilizzando un vero e proprio database di
Edit finale: Dopo alcune e-mail avanti e indietro con Microsoft, si scopre che
TransactionScope
s sono ora autorizzati a SQLCE con l'ultima versione di SqlCE. Tuttavia, se si utilizza EF4 ci sono alcune limitazioni nel fatto che è necessario aprire esplicitamente la connessione al database prima di iniziare la transazione. Il codice seguente mostra un esempio su come utilizzare correttamente SQL CE per l'unità/test funzionali:
[TestMethod]
public void My_SqlCeScenario()
{
using (var context = new MySQLCeModelContext()) //ß derived from DbContext
{
ObjectContext objctx = ((IObjectContextAdapter)context).ObjectContext;
objctx.Connection.Open(); //ß Open your connection explicitly
using (TransactionScope tx = new TransactionScope())
{
var product = new Product() { Name = "Vegemite" };
context.Products.Add(product);
context.SaveChanges();
}
objctx.Connection.Close(); //ß close it when done!
}
}
Ovviamente SQL CE supporta le transazioni ... ma l'uso di TransactionScope è un modo molto sbagliato di farlo. Fallo normalmente tramite l'oggetto Connection. – leppie
Non sono sicuro di come con entità EF4 senza 'TransactionScope', a meno che non si intenda non chiamare' SaveChanges() ', il che significa che i test non sono test validi. – KallDrexx
Puoi fornire un esempio di come seminare i dati con Sql CE? Io uso EF6 e vorrei testarlo usando sql ce –