Unit Testing With NHibernate And SQLite

Good unit tests should, among other things, be easily repeatable and independent. If you're testing against a full blown MySQL or MSSQL server it can become difficult to easily repeat a test if you rely on certain records holding certain Ids, and the independent nature of the test is impacted as it's not well isolated from a specific server.

Testing against an SQLite database can help alleviate these issues as the flatfile database can be created and thrown away after each test, making it easy to repeat a test on fresh data each time.

So let's look at how to go about setting this up.

The Standard SessionFactory

In order to get an NHibernate session normally in my application, I use a provider class to provide access to a SessionFactory:
public static class SessionFactoryProvider
{
private static ISessionFactory sessionFactory;
private static Object lockObj = new Object();

private static void BuildSessionFactory()
{
string connStr = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

sessionFactory = Fluently.Configure().
Database(MsSqlConfiguration.MsSql2005.ConnectionString(connStr)).
Mappings(m => m.FluentMappings.AddFromAssemblyOf()).
BuildSessionFactory();
}

public static ISession OpenSession()
{
if (sessionFactory == null)
lock(lockObj)
if (sessionFactory == null)
BuildSessionFactory();

return sessionFactory.OpenSession();
}
}

This will normally live in the assembly that contains all the data access logic, and will used through dependency injection.

The Test SessionFactory

To get an SQLite database for testing, we need to create it in a slightly different way, specifying a filename for SQLite to use, and providing a way to tear it down after use:
namespace DITests
{
public static class TestSessionFactoryProvider
{
private static ISessionFactory sessionFactory;
private static string dbFile;

private static string GetDbFileName()
{
var path = Path.GetFullPath(Path.GetRandomFileName() + ".Test.db");
if (File.Exists(path))
{
File.Delete(path);
}
return path;
}

private static void BuildSessionFactory()
{
dbFile = GetDbFileName();

sessionFactory = Fluently.Configure().
Database(SQLiteConfiguration.Standard.UsingFile(dbFile).ShowSql()).
ExposeConfiguration(c =>
{
c.Properties.Add("hbm2ddl.keywords", "none");
c.Properties.Add("hbm2ddl.auto", "create");
}).
Mappings(m => m.FluentMappings.AddFromAssemblyOf()).
BuildSessionFactory();
}

public static ISession OpenSession()
{
if (sessionFactory == null) BuildSessionFactory();
return sessionFactory.OpenSession();
}

public static void Teardown()
{
if (sessionFactory != null)
{
sessionFactory.Dispose();
sessionFactory = null;
}

if (File.Exists(dbFile))
{
File.Delete(dbFile);
}
}
}
}

Something To Test

Now that the test session factory is setup, we need something to test, so here's a very simple user class, mapping and repository:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NHibernate;
using NHibernate.Linq;

namespace MVC3DI.Models
{
public class User
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int Age { get; set; }
}

public class UserMap : ClassMap
{
public UserMap()
{
Id(c => c.Id);
Map(c => c.Name);
Map(c => c.Age);
}
}
public class UserRepository
{
ISession session;
private IQueryable Users
{
get { return session.Query(); }
}

public UserRepository(ISession session)
{
this.session = session;
}

public IList GetUsers()
{
using (session.BeginTransaction())
{
var query = from c in Users select c;
return query.ToList();
}
}

public void Save(User user)
{
using (ITransaction t = session.BeginTransaction())
{
session.Save(user);
t.Commit();
}
}
}
}

The Test

And finally, we can setup some tests to run. Because the user repository takes an ISession in its constructor, we can easily change which SessionProviderFactory we're using, allowing us to drop in our test one in order to test against SQLite:
using System;
using System.Collections.Generic;
using NUnit.Framework;
using MVC3DI.Models;

namespace DITests
{
[TestFixture]
public class HireContractDALTests
{
UserRepository repo;

[SetUp]
public void Setup()
{
repo = new UserRepository(TestSessionFactoryProvider.OpenSession());

//insert some test checks
var users = new List(){
new User(){ Name = "Frank", Age = 24 },
new User(){ Name = "Bob", Age = 22 },
new User(){ Name = "Bert", Age = 30 },
};
users.ForEach(p => repo.Save(p));
}

[TearDown]
public void TearDown()
{
TestSessionFactoryProvider.Teardown();
}

[Test]
public void TestTryLoadUsers()
{
var users = repo.GetUsers();
Assert.AreEqual(3, users.Count);
Assert.AreEqual("Frank", users[0].Name);
Assert.AreEqual("Bob", users[1].Name);
Assert.AreEqual("Bert", users[2].Name);
}
}
}

This is a pretty straight forward test which fires up the database, creates a few records, and then reads them back in order to verify that they were saved correctly.

Limitations

The big limitation with this method is that you can only test code that is database agnostic. This should be fine if you're only strictly accessing records through NHibernate as that will take care of creating the correct SQL for you, but if you write any SQL yourself with keywords specific to a certain provider, it will quickly fall over when run against SQLite.

There's not a whole lot that can be done about this; you could extract the database specific functions to a more specific implementation, but then that would need testing too, which you can only do against the database it's targeted at, so that seems a little pointless. Which leaves you with either not testing that code or not writing it in the first place!

Summary

There is some debate as to the value of testing at the database level, especially when you're not testing against the database that will be used in production, but personally I think it can still be useful in verifying that mappings are working correctly and to test any basic logic that may live down at that level.

Using SQLite as a replacement during testing ensures your tests will run quickly and be independant of any outside requirements. Whilst the downside to this is that you can't test vendor specific SQL with this method, it's generally best to avoid this anyway when using an ORM such as NHibernate.

Ninject, MVC3 And Web Requests

Continuing to play with Ninject and MVC3, I wanted to explore further how Ninject can help manage objects over the life of a web request. One of the great things about Ninject is that it allows you to easily change the scope in which objects live through use of Activation Behaviours.

Behave Yourself!

Using Ninject, you can control when new instances of objects are created with Activation Behaviours (although this documentation appears to be out of date at the time of writing).

To set the activation behaviour of a binding, you append a call like so:
Bind().To().InTransientScope();

Ninject has the following scopes built in:

  • TransientScope: A new instance is created for each request.
  • SingletonScope: Only a single instance of an object is created, and the same instance is returned every time.
  • ThreadScope: A new instance is created for each thread.
  • RequestScope: A new instance is created for each web request.

RequestScope and MVC

What I was interested in was whether the RequestScope would create a new instance of something at the start of a web request, and then immediately clean said object up at the end of the request, so that objects wouldn't be kept around longer than they were needed.

A simple test ensued:
public class MvcApplication : NinjectHttpApplication
{
private static ILog logger = log4net.LogManager.GetLogger("default");

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

}

protected override Ninject.IKernel CreateKernel()
{
return new StandardKernel(new MyModule());
}

protected override void OnApplicationStarted()
{
base.OnApplicationStarted();

AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}

public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind().To().InRequestScope();
}
}

public interface ITestInterface { }

public class TestClass : ITestInterface, IDisposable
{
public void Dispose()
{
System.Console.WriteLine("Disposing");
}
}

public class HomeController : Controller
{
ITestInterface test;
public HomeController(ITestInterface test)
{
this.test = test;
}

public ActionResult Index()
{
return View();
}
}

All I did here was setup a controller that would take an instance of a disposable test class. We know it gets created and passed to the controller, so all I wanted to see was that it was disposed at the end of the request. I did this by setting a breakpoint in the dispose method of the class and debugging through Visual Studio.

If you run up the project, you'll see that the breakpoint gets hit after the request has been served, nice and promptly; exactly what I was hoping for.

Making NHibernate Behave

The recommended way or using NHibernate with MVC is to have a single session created per request. That is each time a client makes a request for a page, a new session is opened and kept open until the request is complete and data is returned to the client.

Sounds a little like the RequestBehaviour activation type fits perfectly here doesn't it?

To test this, we need to setup NHibernate and create a simple user class and repository. So to start, here's how I like to get my session factory:
namespace DITest
{
public static class SessionFactoryProvider
{
private static ISessionFactory sessionFactory;
private static Object lockObj = new Object();

private static void BuildSessionFactory()
{
string connStr = ConfigurationManager.ConnectionStrings["SqlServer"].ConnectionString;

sessionFactory = Fluently.Configure().
Database(MsSqlConfiguration.MsSql2005.ConnectionString(connStr)).
ExposeConfiguration(c => c.Properties.Add("hbm2ddl.keywords", "none")).
Mappings(m => m.FluentMappings.AddFromAssemblyOf()).
BuildSessionFactory();
}

public static ISession OpenSession()
{
if (sessionFactory == null)
lock(lockObj)
if (sessionFactory == null)
BuildSessionFactory();

return sessionFactory.OpenSession();
}
}
}

And this is registered with Ninject like so:
Bind().ToMethod(x => SessionFactoryProvider.OpenSession()).InRequestScope();

Next, a simple user class, mapping (I'm using FluentNhibernate here to do the mapping) and repository (all in one place for brevity):
namespace DITest
{
public class User
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int Age { get; set; }
}

public class UserMap : ClassMap
{
public UserMap()
{
Id(c => c.Id);
Map(c => c.Name);
Map(c => c.Age);
}
}

public class UserRepository
{
ISession session;
private IQueryable Users
{
get { return session.Query(); }
}

public UserRepository(ISession session)
{
this.session = session;
}

public IList GetUsers()
{
using (session.BeginTransaction())
{
var query = from c in Users select c;
return query.ToList();
}
}
}
}

Finally, updated the controller to pull some information from the database:
public class HomeController : Controller
{
UserRepository repo;
public HomeController(UserRepository userRepo)
{
repo = userRepo;
}

public ActionResult Index()
{
ViewBag.Users = repo.GetUsers();
return View();
}
}

To verify this was all working correctly and the session is being closed properly, I setup logging to log debug information, which churns out tons of useful information:






Then after running up the page and doing a request, we can look at the generated log and see what's been happening:
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] opened session at timestamp: 634462405708, for session factory: [/b9e13234ae244e18b7f2ce1923c58e48]
14/07/11 12:42:50 DEBUG Begin (Unspecified)
14/07/11 12:42:50 DEBUG Obtaining IDbConnection from Driver
...//edited for brevity
14/07/11 12:42:50 DEBUG IDbTransaction disposed.
14/07/11 12:42:50 DEBUG transaction completion
14/07/11 12:42:50 DEBUG aggressively releasing database connection
14/07/11 12:42:50 DEBUG Closing connection
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] running ISession.Dispose()
14/07/11 12:42:50 DEBUG [session-id=6bf6823c-44d1-4a15-888e-c858a9212024] executing real Dispose(True)
14/07/11 12:42:50 DEBUG closing session
14/07/11 12:42:50 DEBUG running BatcherImpl.Dispose(true)

I've cut out a lot of the logging that just details queries are happening so that we can see what we care about; that the session is being closed properly after the requests have happened, and not before!

Summary

We looked at the various types of activation behaviour that Ninject supports, delved deeper into RequestBehaviour and verified that it is in fact doing what it says on the tin, and then saw how this is useful when working with MVC and NHibernate.

So now we have an NHibernate session that will last for the duration of a request. What would be really useful now is some concept of a unit of work, to allow multiple Nhibernate requests to be batched into a single transaction. Stay tuned!

Ninject And ASP .Net MVC3

I've mentioned Ninject before, it's an excellent dependancy injection framework that lets you keep your code loosely coupled.

I've also mentioned that I've been working with the MVC Framework quite a lot of late, and what's neat is that hooks are provided that make it easy to use your own dependancy injection framework. To that end, this post will be looking at how Ninject can be integrated with MVC3, and why that's awesome!

I'll be working with a clean MVC3 project created in Visual Studio 2010. There are a couple of ways of integrating Ninject; using the IDependancyResolver interface, or inheriting from NinjectHttpApplication.

Option 1: IDependancyResolver

All we need to do here is implement IDependancyResolver and then register an instance of it on application startup.

So a simple implementation for Ninject will look something like this:
using System;
using System.Web.Mvc;
using System.Collections.Generic;
using Ninject;
using Ninject.Modules;

public class NinjectResolver : IDependencyResolver
{
IKernel kernel;

public NinjectResolver(INinjectModule[] modules)
{
kernel = new StandardKernel(modules);
}

public object GetService(Type serviceType)
{
return kernel.Get(serviceType);
}

public IEnumerable GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
}

And we register this in Application_Start with a simple call like so:
var resolver = new NinjectResolver(new MyModule());
DependencyResolver.SetResolver(resolver);

MVC3 will then use this object when trying to instantiate an instance of a class, but will fall back to it's built in methods for locating objects if this fails. What this means in practice is that you don't need to worry about registering all of the default objects MVC3 uses such as the controller factory, leaving you free to just deal with the stuff you care about.

Option 2: NinjectHttpApplication

The second option is to make use of Ninject's MVC3 extension which can be found here.

In this case, all we need to do is change our MvcApplication class (found in Global.asax) to inherit from NinjectHttpApplication instead of MvcApplication, and then implement CreateKernel to register the modules we've created.

public class MvcApplication : NinjectHttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

}

protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}

public override IKernel CreateKernel()
{
return new StandardKernel(new MyModule());
}
}

And that's it; now Ninject will be used to resolve any dependencies that are requested when the object model is being built.

Which Approach?

But which of the two approaches should you use? It doesn't matter hugely, the first option allows for a very quick integration, you could even register a dependency resolver in a much more concise fashion making use of lambdas like so:
var kernel = new StandardKernel(modules);
DependencyResolver.SetResolver(
t => {
try { return kernel.Get(t); }
catch { return null; }
},
t => kernel.GetAll(t)
);

However, using Ninject's MVC3 extension is marginally more self contained, so I tend to prefer making use of NinjectHttpApplication instead. Note that Ninject will still find the right controllers without registering them, so there is no need to register all your controllers unless you want to add additional configuration to them.

If you think you're likely to want to change your DI framework, then it would make more sense to make use of the IDependancyResolver interface so that you can drop in a quick replacement, although personally I think that scenario is somewhat unlikely.

Now you're loosely coupled

So that's a couple of simple ways to integrate Ninject with MVC3; not too hard to achieve and provides a lot of power and flexibility.

Writing A Simple Jquery Plugin

Jquery is a fantastic Javascript library that makes manipulating the DOM a breeze. Its usefulness lies in the powerful selectors which make it easy to pick which part of the DOM you want to work with, and many functions with which to manipulate the selected objects.

Jquery provides a lot of functionality, but like any good library, also provides the ability to easily extend its capabilities. I recently found it useful to do this, so here's a quick run down on how to do just that.

The Barebones

To start with we'll just put together a bare plugin so that we can see the structure:

(function($) {
$.fn.mask = function() {
//body goes here
};
})(jQuery);

This adds a new function, mask, to the jquery object. You could use it like so:


$('#objectToMask').mask();

An Overlay

The reason I started to look into this was that I wanted to encapsulate a piece of functionality that would allow an overlay mask to be applied to an arbitrary element. This is useful when loading something asynchronously to let the user have some visual feedback.

Firstly the mask function:
(function($) {
$.fn.mask = function() {
if ($("#overlay").length == 0) {
var $overlay = $('

');
$("body").append($overlay);
}

$("#overlay").css({
opacity: 0.5,
top: this.offset().top,
left: this.offset().left,
width: this.outerWidth(),
height: this.outerHeight()
});

$("#img-load").css({
top: (this.height() / 2),
left: (this.width() / 2)
});

$("#overlay").fadeIn();
};
})(jQuery);

This is pretty straight forward; We create the overlay element if it doesn't exist, set its position along with the loading image position, and then fade it in.

The unmask function, is shorter, as it just needs to hide the element:

(function($) {
$.fn.unmask = function() {
$("#overlay").fadeOut();
};
})(jQuery);

Summary

And that's all there is to it. Extending Jquery is a relatively simple and straightforward process that's well worth investigating when you want to encapsulate a piece of functionality to make it easily reusable.

Jquery Auto-Complete with ASP .Net MVC

I've been doing a lot of work with Microsoft's MVC Framework over the past few weeks, having been a convert to the MVC way of doing things for some time.

A customer requested a feature to select an item using a popup form that would allow the user to search and select the relevant entry. I decided this could be achieved in a less obtrusive manner by using an auto-complete field a la google suggest.

Google Auto Complete

The Jquery UI library features a number of useful UI elements, with an auto-complete widget among them, so this is what I decided to use.

The MVC Controller

We'll start off implementing the backend, which will be an action in a controller that will return a JSON result.

public ActionResult Customers(string term)
{
List list = new List{
new Customer(){AccountName = "Test Company 1", AccountNum = "1234"},
new Customer(){AccountName = "Another Test 2", AccountNum = "1235"},
new Customer(){AccountName = "Another Company 3", AccountNum = "1236"},
new Customer(){AccountName = "Testing Account 4", AccountNum = "1237"},
new Customer(){AccountName = "Late Company", AccountNum = "1238"},
new Customer(){AccountName = "Test Company", AccountNum = "1239"},
};
return Json(list.Where(c => c.AccountName.Contains(term)));
}

In this case I'm just putting together a list of mock data and returning it as a JSON result using MVC's built in Json encoding functionality.

The only other thing to note here is the function argument term which contains the search term that will be entered into the auto-complete box. This is what will be used to filter our data.

Obviously in an actual implementation we'd be calling out to our data access layer to do the querying, but for the sake of example I'll be keeping this simple.

Jquery UI

Now that we have some data to work with, let's pull it down and display it. First the HTML:

And then the JavaScript:
$(document).ready(function() {
$('#customer_search').autocomplete({
source:'/POD/Customers',
minLength: 3,
select : function(event, ui){
$( "#customer_search" ).val( ui.item.AccountName );
//here we might want to store ui.item.AccountNum etc...
return false;
},
focus: function( event, ui ) {
$( "#customer_search" ).val( ui.item.AccountName );
return false;
},
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "

  • " )
    .data( "item.autocomplete", item )
    .append( "" + item.AccountName + " (" + item.AccountNum + ")" + "" )
    .appendTo( ul );
    };
    });

    The important things to note here:

    • Select Function: We're setting the select function to allow us to handle what happens when the user selects an item ourselves. Returning false prevents the default handler from running.
    • Focus function: As above, we're handling focus ourselves so that we can display the custom data field of our choosing. By default the 'value' property would be used.
    • Render Item: We're overriding this to give us control over how data is presented in the drop down list that is shown whilst searching. Again this allows us to display custom data fields, rather than the default 'value' field that the auto-complete field expects.

    You should end up with something like this:

    Summary

    So there we have it, a simple example of how to hook up Jquery auto-suggest to an ASP .Net MVC controller with custom data. Enjoy!

    Dependancy Injection And Ninject

    I'm going to look at another useful item to have in your developer toolbox today: Dependancy Injection.

    What Is It And Why Should I Care?

    Dependancy Injection is a pretty large topic in itself, but what it boils down to is breaking down tightly coupled classes by using interfaces to provide a level of indirection. There is a good example of this on the Ninject Wiki.
    class Samurai {
    readonly Sword _sword;
    public Samurai() {
    _sword = new Sword();
    }
    public void Attack(string target) {
    _sword.Hit(target);
    }
    }

    If we wanted to break the tight coupling between a Samurai and his sword, to allow the samurai to attack with any weapon, we could do the following:
    class Samurai {
    private IWeapon _weapon;
    public Samurai(IWeapon weapon) {
    _weapon = weapon;
    }
    public void Attack(string target) {
    _weapon.Hit(target);
    }
    }

    This allows us to provide the samurai with any weapon that implements the IWeapon interface, removing the tight coupling between the samurai and his weapon. This is the essence of Dependancy Injection.

    My framework of choice is Ninject, so let's look at how to setup a project to use it.

    Setting Up Ninject

    There are two things we need to do to setup Ninject, the first is to setup a module that will register all our dependancies:
    class ExampleModule : StandardModule
    {
    public override void Load()
    {
    Bind().To();
    Bind().To();
    }
    }

    Next thing to do is create a kernel; this acts as a repository that will let us request instances of the types we registered.
    IKernel kernel = new StandardKernel();

    Example Usage

    Now that the setup has been completed, we can access the object repository using the kernel:
    Samurai s = kernel.Get();

    As the kernel uses generics, we can get a strongly typed result. Now, assuming we used the second class definition of Samurai which has a constructor with an IWeapon argument, we'll receive an instance of a Samurai with a sword weapon. When creating new object instances, Ninject will check what parameters an object's constructor requires, create new instances of each and inject them automatically. This is how we ended up with a Samurai with a sword, as our config specified that when an IWeapon object is required, a Sword should be provided.

    This can become massively useful in a number of ways. For example. say you want to add logging to a class, simply include an ILogger in the constructor, and start logging. You don't need to worry about setting up the logger as that's conveniently handled elsewhere. Need to change the method of logging? Change it in the one place and feel a smug satisfaction that you don't need to check through all your code for that one place where you dealt with it differently.

    Activation Behaviours

    "But what if I don't want a new instance every time?" I hear you ask. Ninject provides some flexibility in how new objects are created through Activation Behaviours.

    For example, if we only wanted a single instance of a given class, we could configure it like so:
    Bind().To().Using();

    Or say we're writing a multi-threaded application, and only wanted one instance of a particular class per thread:
    Bind().To().Using();

    The other supported behaviours are TransientBehaviour, which is the default and creates a new object every time it is requested; and OnePerRequestBehavior, which will create an object instance once for each web request.

    Summary

    So hopefully you now have an idea of what Dependancy Injection is, what it can do for you, and how to get a simple application architecture up and running with Ninject.

    Ninject provides a lot more flexibility than has been presented here, allowing for much more complex activation scenarios: an entire object graph can be created with a single call to IKernel.Get. When you have an object graph several levels deep, this can really help in ensuring things are created in a consistent manner.