Ivan's Brain Dump




read

Lately I have been using Fluent NHibernate and NHibernate respectively for my ORM (Object-Relational Mapping) when working on my top secret pet project. Simply put – it’s great. Mapping is done using a fluent C# interface which makes use of lambda expressions for referencing properties instead of strings (check my previous post for more info) so the domain model is safe to refactor because the mapping will be kept up-to-date too.

I spend some time hacking on Fluent NHibernate to add three little features I needed for my integration unit testing via Fluent NHibernate’s PersistenceSpecification. They all currently live in my GitHub(also used by Fluent NHibernate) fork here and have all been submitted upstream. UPDATE: The changes are as of now (21.12.2009) officially part of Fluent NHibernate. I can only hope you will find them useful as well.

PersistenceSpecification: More Informational Error Reporting

Particularly useful to troubleshoot failing mapping integration unit tests when a property check fails it will print both expected and actual types of the values. Also notice that chained properties (object.PropA.PropB) are now supported as well:

For property ‘Nutrition.Calories’ expected ‘400’ of type ‘System.Int32′ but got ‘400’ of type ‘System.Single’.

instead of:

Expected ‘400’ but got ‘400’ for Property ‘NutritionCalories’

PersistenceSpecification: Entity Components Property Testing

It is now possible to test entity component properties. For example given this domain model:

public class Food
{
    public Food ()
    {
        Nutrition = new NutritionInfo ();
    }

    public virtual NutritionInfo Nutrition { get; protected set }
    public virtual int Id { get; set; }

}

public class NutritionInfo
{
    public virtual float? Fat { get; set; }
}

and this mapping:

public class FoodMap : ClassMap<Food>
{
    public FoodMap ()
    {
        Id (food => food.Id)
            .GeneratedBy.Native ();

        Component<NutritionInfo> (food => food.Nutrition,
            mapping => {
                mapping.Map (nutrition => nutrition.Fat)
                    .Nullable ();
            }
        ).Access.BackingField ();
    }
}

One can now use this in unit tests:

[TestMethod]
public void Food_Mapping ()
{
    new PersistenceSpecification<Food> (Session)
    .CheckProperty (food => food.Id, 1)
    .CheckProperty (food => food.Nutrition.Fat, 40f) // <-- This one
    .VerifyTheMappings ();

}

Prior to my patch this wasn’t possible because Fluent Nhibernate PersistenceSpecification did not support chained properties and was trying to set a Fat property on the food object. Note that this is useful only for components and not references. For the latter *.CheckReference (…) *should be used which will also commit the reference to the Database before doing anything else.

PersistenceSpecification: IEqualityComparer for Individual Properties

Given the setup from above it is now possible to set an IEqualityComparer per property, e.g.:

[TestMethod]
public void Serving_Mapping ()
{

    new PersistenceSpecification<Food> (Session, new EqualityComparerForAllProperties ())
    .CheckProperty (food => food.Id, 1)
    .CheckProperty (food => food.Nutrition.Fat, 40f, FloatEqualityComparer.Instance)
    .VerifyTheMappings ();
}

If there is no comparer set for the property it will fall back to using the EqualityComparerForAllProperties and if that is not specified it will just use Object.Equals.

Blog Logo

Ivan Zlatev


Published

Image

Ivan's Brain Dump

Back to Overview