Nuova versione per EF Mapping Verifier

di Marco De Sanctis, in ORM,

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

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese