Ho appena messo online una nuova versione per il mio tool di testing del corretto salvataggio delle entities con ADO.NET Entity Framework. Ripeto ancora, a scanso di equivoci, di essermi ispirato ad un’analoga funzionalità presente su Fluent NHibernate.
Come funziona… Diciamo che avete il vostro modello di dominio, solite robe… Customers, Orders, ecc.ecc. e volete vedere se effettivamente ciò che salvate e ciò che recuperate sono la stessa cosa. EF MappingVerifier è ciò che fa per voi :D
Utilizzando delle comodissime e sintetiche lambda expression, è possibile “valorizzare” le proprietà desiderate su una entity, poi il mio tool si occuperà di salvarla, ricaricarla e confrontare i risultati.
Vediamo un po’ nel dettaglio come usarlo.
Proprietà scalari di una entity
La sintassi è molto semplice:
using (new TransactionScope()) using (var ctx = new testDbEntities()) { VerifyMapping.For<Customer>(ctx) .Test(c => c.Name, "Marco") .Execute(); }
Notate l’uso di un TransactionScope che non viene mai committato, in questo modo è possibile far sì che tutti i test siano indipendenti, visto che nulla viene effettivamente memorizzato in maniera permanente sul server.
Complex types
I complex types non sono molto utilizzati in EF, quantomeno nella prima versione, visto che non sono supportati direttamente dal designer. In ogni modo, è possibile testarli con la sintassi seguente, avendo cura di fornire un IEqualityComparer che sia in grado di verificarne l’uguaglianza.
using (new TransactionScope()) using (var ctx = new testDbEntities()) { VerifyMapping.For<Customer>(ctx) .Test(c => c.Name, "Marco") .Test(c => c.Address, new Address { Via="Piazza Duomo", Civico = "15"}, IAddressComparer ) .Execute(); }
Relazioni molti-a-uno
Questo tipo di relazioni sono testabili a patto di aggiungere preventivamente l’altra entity al context.
using (new TransactionScope()) using (var ctx = new testDbEntities()) { City city = new City { Name = "Milano" }; ctx.AddToCitySet(city); VerifyMapping.For<Customer>(ctx) .Test(c => c.Name, "Marco") .Test(c => c.City, city ) .Execute(); }
Dovrebbe funzionare anche all’interno di complex types, ma non l’ho mai provato francamente. Si noti che City deve essere creata separatamente e aggiunta al context.
Relazioni uno-a-molti
La sintassi è leggermente diversa, nel senso che in questo caso bisogna scrivere una lamdba che simuli l’aggiunta di dettagli alla collection del parent:
using (new TransactionScope()) using (var ctx = new testDbEntities()) { VerifyMapping.For<Customer>(ctx) .Test(c => c.Name, "Marco") .Test(c => c.Orders.Add(new Order())) .Execute(); }
La sintassi supporta i metodi Add e AddRange (è previsto anche un extension method per “aggiungere” AddRange a IList<T>). Si noti che è anche possibile utilizzare la entity under test nel caso in cui sia necessario referenziarla nel dettaglio, ad es.:
.Test(c => c.Orders.Add(new Order { Customer = c }))
Il controllo effettuato è squisitamente numerico, nel senso che viene verificato che i dettagli siano dello stesso numero e tipo di quelli impostati nelle lambda. Questo non è un limite, in quanto poi la corretta persistenza di Order va testata con un bel VerifyMapping.For<Order>.
Un’ultima nota sulla metodologia utilizzata per lo sviluppo. E’ stato scritto tutto in TDD (il progetto di test è incluso) e c’è quasi un centinaio di unit test a supporto del codice scritto. Ho “rispolverato” il TDD dopo un annetto di tempo e mi diverte sempre un sacco utilizzarlo. Ah.. per gli scettici che pensano sia una perdita di tempo, probabilmente senza TDD a quest’ora sarei MOLTO indietro.
Il download lo trovate qui.
Enjoy
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
- Inside ModelVirtualCasting #1: Introduzione ai repository, il 27 maggio 2010 alle 07:30
- Testare il mapping di Entity Framework, il 17 settembre 2009 alle 09:00
- Basta! Italia 2009 - I'll be there!, il 13 marzo 2009 alle 17:01
- Gli ORM e la many to one: 3 approcci differenti, il 13 gennaio 2009 alle 18:01
- Alcune info per chi usa NHibernate, il 6 ottobre 2008 alle 08:34