Geeks With Blogs
// ThomasWeller C#/.NET software development, software integrity, life as a freelancer, and all the rest

Let's face it: Setting up NHibernate is not one of the easiest tasks. You need a good knowledge of the system, and you need to write some configuration xml to your config files (well, normally). This is not such a big deal for the main project, since you only have to do it once in a project's lifetime. But you also have to care about setting it up for each and every test project that uses NHibernate, and there might be a lot of them if you're consequently unit testing just about everything.

So, wouldn't it be nice if declaring a test fixture with NH-support would be as easy as this:

[TestFixture]

public class SampleFixture : NHibernateFixtureBase

{

    public SampleFixture()

        : base("Some.Mapping.Assembly", "SOMESERVER", "SOMEDB", "test", "test")

    {

    }

 

    [Test]

    public void TestMethod()

    {

        using (ISession session = SessionFactory.OpenSession())

        {

            // test code goes here...

        }

    }

}

As you can see, you just have to specify the name of the assembly with the relevant NH mappings in the constructor, together with the database credentials, and that's it. The base class then creates the appropriate SessionFactory instance for you on the fly, without any additional configuration. Here it is:

using System.Reflection;

using NHibernate;

using NHibernate.ByteCode.Castle;

using NHibernate.Cfg;

using NHibernate.Dialect;

using NHibernate.Driver;

using Environment=NHibernate.Cfg.Environment;

 

namespace DbDevelopment.Persistence.Test.Common

{

    /// <summary>

    /// Base class for a test fixture with NHibernate + MS  SQL Server support.

    /// </summary>

    /// <remarks>

    /// Use the c'tor to specify the mapping-assembly and the database credentials.

    /// </remarks>

    public abstract class NHibernateFixtureBase

    {

        #region Fields

 

        protected ISessionFactory SessionFactory;

 

        #endregion // Fields

 

        #region Construction

 

        protected NHibernateFixtureBase(string assemblyWithMappings,

                                        string serverName, string databaseName,

                                        string username, string password)

        {

            CreateSessionFactory(

                assemblyWithMappings,

                BuildConnectionString(serverName, databaseName, username, password));

        }

 

        #endregion // Construction

 

        #region Implementation

 

        private void CreateSessionFactory(string assemblyName, string connectionString)

        {

            Assembly assemblyWithMappings = Assembly.Load(assemblyName);

 

            this.SessionFactory = new Configuration()

                .SetProperty(Environment.ReleaseConnections, "on_close")

                .SetProperty(Environment.Dialect, typeof(MsSql2005Dialect).AssemblyQualifiedName)

                .SetProperty(Environment.ShowSql, "true")

                .SetProperty(Environment.ConnectionDriver, typeof(SqlClientDriver).AssemblyQualifiedName)

                .SetProperty(Environment.ConnectionString, connectionString)

                .SetProperty(Environment.ProxyFactoryFactoryClass,typeof(ProxyFactoryFactory).AssemblyQualifiedName)

                .AddAssembly(assemblyWithMappings)

                .BuildSessionFactory();

        }

 

        private static string BuildConnectionString(string serverName, string databaseName,

                                                    string username, string password)

        {

            return string.Format(

                "Data Source={0};Initial Catalog={1};User ID={2};Password={3}",

                serverName, databaseName, username, password);

        }

 

        #endregion // Implementation

 

    } // class NHibernateFixtureBase

 

} // namespace DbDevelopment.Persistence.Test.Common

This example uses a MS SQL Server database (2005 or higher), but it could be easily modified to target a different DBMS by adjusting the BuildConnectionString() method along with the relevant configuration settings in CreateSessionFactory() accordingly.

Happy testing...

 

kickit
shoutit
delicious facebook digg reddit linkedin stumbleupon technorati mrwong yahoo google-48x48 twitter email favorites
Posted on Thursday, September 10, 2009 12:14 PM Unit Testing/TDD , NHibernate | Back to top


Comments on this post: Unit testing with built-in NHibernate support

# re: Unit testing with built-in NHibernate support
Requesting Gravatar...
Unit tests usually don't hit remote database servers. We do our NHibernate based unit testing using an in memory database with SQLite. It works out well and it keeps our tests isolated.
Left by Shaun on Sep 11, 2009 1:23 PM

# re: Unit testing with built-in NHibernate support
Requesting Gravatar...
Shaun,

sorry, but I have a totally different view on this in two respects:

1.
I consider the usage of SQLite for unit tests of this kind in general not a good idea. Because SQLite does not have all the features of a 'real' DBMS (e.g. no foreign key constraints), you create a testing environment that does not match your targeted production environment (by design!), and therefore such tests are useless in the strict sense. You can also read about this here (see the comments): http://devlicio.us/blogs/krzysztof_kozmic/archive/2009/08/17/adjusting-nhibernate-mapping-for-tests.aspx

2.
'Remote' in this context does of course not mean that you have one centralized database against that everyone is doing tests simultaneously. This of course would be a really bad idea. Normally I set these tests up so that the actual db credentials are read from some sort of local configuration and point to a local instance of the db for the actual testing on a developer's machine.

Your solution might work, but it does not safely protect you from faults in any situations. And even worse: if such a test produces an error, you cannot be sure if there's really something broken in your code or if it's just a test artifact.

- Thomas
Left by Thomas Weller on Sep 11, 2009 2:09 PM

Your comment:
 (will show your gravatar)


Copyright © Thomas Weller | Powered by: GeeksWithBlogs.net