Jan Blaha

Blog about software development

Prepare unit tests hierarchy

architecture testing

In the last post was proposed using state testing rather than behavior mock testing when it’s not necessary. This means testing results of methods is most of the time much more convenient and I would recommend using mocks only when it’s necessary. But what about interaction with other components like database or file system? It’s usually way easier to just insert test data to the database than to mock whole layer. Only little problem is that the database must be prepared before the test is running and the concurrent tests should not affect each other. The solution for this is to have a good infrastructure.

I prefer to have infrastructure for tests interacting with the database based on class hierarchy. If I want to create a new test interacting with the database I just need to inherit from correct class and whole magic is done in base. The very top base class for tests accessing database should be responsible to recreate the database once and initialize ORM session for every test method. It can look like following class.

[TestFixture]
public class where_test_access_database
{
    protected ISession Session;

    //run just once, this is time consuming
    static where_test_access_database()
    {
        //drop database.. I prefere to use script
        //create schema.. I prefere to use ORMs code first methods
    }

    [SetUp]
    public void where_test_access_database_setUp()
    {
        //get NH Session or EF Object Context
        Session = InjectionContainer.Instance.Resolve<ISession>();
    }

    [TearDown]
    public void where_test_access_database_tearDown()
    {
         //release all resources
         Session.Dispose();
    }
}

Most of the tests will be probably working with the same database and could affect each other. Therefor I prefer to run tests in the database transaction so they are isolated from each other. Let’s introduce another base class for this that is providing transactional behavior for tests.

[TestFixture]
public class when_test_running_in_transaction : where_test_access_database   
{      
   [SetUp]
   public void when_test_running_in_transaction_setUp()
   {
     Session.Transaction.Begin(); 
   }

   [TearDown]
   public void when_test_running_in_transaction_tearDown()
   {
     Session.Transaction.Rollback();
   }
}

Every single test method in class inheriting from when_test_running_in_transaction will have easy access to the database and it’s work will not affect other tests. You can continue this way and create another test base classes that will help you easier implement specific test types like persistence tests and so on.

In the next post I will show you some good tips for easier preparing and inserting test data to database.

last blog posts


09-12-2017 18:40 jsreport

Quite some time ago I blogged about rendering pdf reports in c#. Recently we have added excel reports into jsreport and it was released with a little delay also into .NET. This means you should be able to use both html-to-xlsx and xlsx recipes to create excel files from your .NET environments now.

read more

09-10-2015 14:09 AWS

Such a very common thing like adding an existing external volume to Amazon elastic beanstalk is not easily supported out of the box. The official blog mentions only how to attach a snapshot or how to attach and overwrite a new volume every time the service starts. It took me a while to make the config file actually adding an existing volume without formatting it every time so I share it here with you...

read more

04-10-2015 14:09 jsreport

The best practice when adding email notifications feature to your system is to separate as much as you can from email body assembling to email sending outside of the core system. The emails templates quite likely often changes and you don't want to deploy the system because of every single notification change. The best is to just separate everything into an external system and give the access to your PR or Marketing department so they change emails as the time goes without affecting the core system.

read more

Jan Blaha

About author

Hi! My name is Jan Blaha. I'm software developer and startup enthusiastic. See my current work.