SQLite Nunit & Fluent Nhibernate - Test your data access layer

Download Code

I think that the worst part of unit testing is that it’s never straight forward to test an applications data access. I always feel worried about just creating in memory collections or objects to test against or mocking data access components. I have found on occasion when the code is switched over from test data to work against an RDBMS issues can occur. What I really want is an in memory database that is created with test data and then disposed of once the tests have been carried out.

Below is a class which will generate an in memory SQLite database based on the model and Nhibernate fluent mappings created (if you don't know how to create the mappings and model then read here). The important line of code here is on line 18 which looks in the assembly where the fluent mappings are located so the framework is able to generate the database schema.

using System;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using Nhibernate.Blog.Data.Helpers;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;

namespace Nhibernate.Blog.Test.DatabaseSetup
{
    public abstract class InMemoryDatabase : IDisposable
    {
        private static Configuration _configuration;
        private static ISessionFactory _sessionFactory;

        protected ISession Session { get; set; }

        protected InMemoryDatabase()
        {
            _sessionFactory = CreateSessionFactory();
            Session = _sessionFactory.OpenSession();
            BuildSchema(Session);
        }
        private static ISessionFactory CreateSessionFactory()
        {
            return Fluently.Configure()
                .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
                .Mappings(M => M.FluentMappings.AddFromAssemblyOf<SessionFactory>())
                .ExposeConfiguration(Cfg => _configuration = Cfg)
                .BuildSessionFactory();
        }
        private static void BuildSchema(ISession Session)
        {
            SchemaExport export = new SchemaExport(_configuration);
            export.Execute(true, true, false, Session.Connection, null);

        }

        public void Dispose()
        {
            Session.Dispose();
        }
    }
}

Now you will have an ISession object which you can add test data to. The InMemoryData class inherits from the InMemoryDatabase class so it has the ISession available to it. By calling Session.Save(object); and then Session.Flush(); the Entity will be added to the SQLite database.

using Nhibernate.Blog.Model;

namespace Nhibernate.Blog.Test.DatabaseSetup
{
    public abstract class InMemoryData : InMemoryDatabase
    {
        protected InMemoryData()
        {
            Account AccountOne = new Account(1, "AC001");
            Account AccountTwo = new Account(2, "AC002");

            Session.Save(AccountOne);
            Session.Save(AccountTwo);

            Session.Flush();
            
            Session.Save(new Person(1, "Dan", "Watson", AccountOne));
            Session.Save(new Person(1, "James", "May", AccountTwo));
            Session.Save(new Person(1, "Andrew", "Plum", AccountOne));
            
            Session.Flush();
        }
    }
}

Using Nunit (or your test framework of choice) create a base class that inherits from the InMemoryData class so all the data tests have access to the Nhibernate Session. I created data repository classes which have overloaded constructors which accept an ISession object. Now you will be able to run methods in the data access layer against the in memory SQLite database.

using Nhibernate.Blog.Data.Interfaces.Repository;
using Nhibernate.Blog.Test.DatabaseSetup;
using NUnit.Framework;
using Nhibernate.Blog.Data.Repository;

namespace Nhibernate.Blog.Test.Base
{
    [TestFixture]
    public abstract class TestBase : InMemoryData
    {
        protected IPersonData PersonData { get; set; }
        protected IAccountData AccountData { get; set; }

        [SetUp]
        public void Init()
        {
            PersonData = new PersonData(Session);
            AccountData = new AccountData(Session);
        }

        [TestFixtureTearDown]
        public void Die()
        {
            Dispose();
        }

    }
}

You can now call the methods in your data access classes and make assertions based on the test data added to the SQLite database. Just remember to inherit from you test base class which set’s up the in memory database, data and data access classes.

using System.Linq;
using Nhibernate.Blog.Test.Base;
using NUnit.Framework;

namespace Nhibernate.Blog.Test.DataTests
{
    public class PersonDataTest : TestBase
    {
        [Test]
        public void Select_All_People_Should_Return_3()
        {
            Assert.AreEqual(3, PersonData.SelectAllPeople().Count());
        }
    }
}

Unit testing

An added bonus to this method of data access testing is you are able to see the SQL statements generated for both the schema and also each unit test run which makes it much easier to debug issues when developing the code.
image

Although there are a few levels of inheritance once it is setup its really easy to maintain and makes unit testing easy to carry out.  You can download the sample code from here (you will need VS2008 Standard / Pro / Team to run this or if your über cool use VS2010 beta).

Twitter Twitter Twitter Twitter Twitter
October 20, 2009 10:26 by DanWatson

Comments

October 17. 2009 22:38

trackback

SQLite Nunit & Fluent Nhibernate - Test your data access layer

Thank you for submitting this cool story - Trackback from DotNetShoutout

DotNetShoutout

October 17. 2009 22:40

trackback

SQLite Nunit & Fluent Nhibernate - Test your data access layer

DotNetBurner - burning hot .NET content

DotNetBurner - NHibernate

October 17. 2009 22:56

Jon Kruger

Awesome stuff... thanks for the post.

Jon Kruger

November 8. 2009 16:02

Latex Mattress

great tips - the pictures help out

Latex Mattress

November 9. 2009 07:40

vitamin c

You described this article very beautifully with pictures too. So every one can easily understand it. Keep posting such a way as I can keep visiting this blog very often. Thanks for this great post.

vitamin c

November 27. 2009 13:12

Our simply

great tips - the pictures help out

Our simply

November 30. 2009 23:01

short jokes

data access layer is an good technical post which need to understand and good results comes up after use. thanks !!!

short jokes

December 2. 2009 18:16

life jackets

The article is really interesting. Even the Example given in the article shows how we can do access the Data layer.

life jackets

December 29. 2009 10:28

homeowner loans

some interesting style there but i guess content is more important. nice one

homeowner loans

January 20. 2010 20:50

Wiring Diagram

Thank you for sharing, interested story.

Wiring Diagram

February 8. 2010 11:33

Free Club Penguin

This code helped me greatly.

Free Club Penguin

February 8. 2010 21:01

cheap printer ink

Hi,
Interesting read, thanks for helping keep me busy at work ;)

cheap printer ink

Add comment



(Will show your Gravatar icon)



 
Are you human? number7 + number7 =