Testare il mapping di NHibernate

Un buon mapping è la base di un buon risultato ottenibile tramite l’uso di un O/RM.
Anche se in molti esempi può sembrare semplice effettuare il mapping, in applicazioni reali (o con particolari richieste) questo può essere tutt’altro che semplice.
In Dexter ho avuto la necessità di realizzare diversi UserType per gestire enumerati, timezone, conversioni, ecc, ed ovviamente, essendoci una logica di calcolo dietro, questi andrebbero testati per evitare di avere un’incongruenza di dati o, nel peggiore dei casi, degli errori.
FluentNHibernate mette a disposizione delle classi che permettono di effettuare lo UnitTest del mapping verificando così che la CRUD della entity funzioni a dovere; quindi, nello specifico, si ha a disposizione un mini Framework per testare le seguenti operazioni:

  • Inserimento della entity;
  • Modifica della entity;
  • Recupero della entity;
  • Cancellazione della entity;

Lo snippet seguente mostra come effettuare questo tipo di test con poche righe di codice, avendo la certezza che il mapping sia corretto:

[TestMethod]
public void BlogRollMap()
{
    new PersistenceSpecification<BlogRoll>(session)
        .CheckProperty(c => c.ID, 1)
        .CheckProperty(c => c.Co_worker, true)
        .CheckProperty(c => c.Colleague, true)
        .CheckProperty(c => c.Crush, true)
        .CheckProperty(c => c.Date, true)
        .CheckProperty(c => c.FamilyType, BlogRollFamilyType.Sibling)
        .CheckProperty(c => c.FriendType, BlogRollFriendType.Contact)
        .CheckProperty(c => c.GeographicalType, BlogRollGeographicalType.Neighbor)
        .CheckProperty(c => c.IsMyBlog, true)
        .CheckProperty(c => c.Link, "http://www.microsoft.com")
        .CheckProperty(c => c.Met, true)
        .CheckProperty(c => c.Muse, true)
        .CheckProperty(c => c.Name, "Microsoft")
        .CheckProperty(c => c.Position, 1)
        .CheckProperty(c => c.Sweetheart, true)
        .CheckProperty(c => c.Username, "imperugo")
        .VerifyTheMappings();
}

Inoltre per condizioni particolari è possibile specificare, tramite l’apposito overload del costruttore, una classe IEqualityComparer per effettuare una comparazione custom dei dati, come mostrato di seguito:

public class SiteConfigurationEqualityComparer : IEqualityComparer
{
    public new bool Equals(object x, object y)
    {
        if (x == null || y == null)
            return false;

        if (x is TimeZoneInfo && y is TimeZoneInfo)
            return ((TimeZoneInfo)x).Id == ((TimeZoneInfo)y).Id;

        if (x is ReCaptcha && y is ReCaptcha)
        {
            var r1 = (ReCaptcha)x;
            var r2 = (ReCaptcha)y;

            return (r1.Enable == r2.Enable &&
                    r1.PrivateKey == r2.PrivateKey &&
                    r1.PublicKey == r2.PublicKey &&
                    r1.Theme == r2.Theme);
        }
}

Maggiori info sono disponibili qui.

Ciauz


Comments