Testing the NuSoft Framework

posted on 07/09/08 at 12:45:25 am by Joel Ross

NuSoftFrameworkI've started up a new project that is using the NuSoft Framework, and because of some of the interactions, I realized it would be much, much easier if I had a set of automated tests, rather than going through the process of firing up an application, going through a WCF service, and then eventually hitting the code I needed to test.

I realize this isn't earth shattering for those used to doing TDD or unit testing, but it's not something that I've done a lot of in the past. On one project, we had well north of 100 tests, but they were all isolated to a particular hairy part of the code and it was rather self-contained.

To be honest, the NuSoft Framework is not ideal for unit testing, since the data persistence is pretty well embedded into the entities. That's OK in my mind, since I've rarely seen a case where my persistence layer has changed. Once, I knew I had to build for different databases, but that was known up front, and not added after the fact. That may be viewed as a naive attitude, but it's worked for me so far.

Anyway, there's a reason I didn't call this "unit testing" but rather referred to it as just testing. It's not unit testing, since it's not testing just one thing. It's more like an integration test, since it's also going to rely on a known state of the database.

Essentially, what you have to do is manage your own transaction, and then at the end, after you assert that your desired action worked, you roll it back, leaving the database untouched. If you want to isolate your tests in their own assembly, you're going to need to add an attribute to your business layer so you can gain access to some of the internals of the business layer:

   1:  [assembly: InternalsVisibleTo("Northwind.Tests")]

This gives us the ability to call one of the internal overloads on Save() where you can pass in a helper. This ensures the Save will participate in the existing transaction, and not create its own (which it does when you call Save() with no parameters). Here's an example that would test being able to insert a customer:

   1:  [Test]
   2:  public void CanInsertCustomer()
   3:  {
   4:    Customer customer = Customer.CreateCustomer();
   5:    customer.CustomerId = "jross";
   6:    customer.FirstName = "Joel";
   7:    customer.LastName = "Ross";
   8:   
   9:    using (SqlHelper helper = new SqlHelper())
  10:    {
  11:      try
  12:      {
  13:        helper.BeginTransaction();
  14:        customer.Save(helper);
  15:        Assert.That(customer.IsNew == false, "customer.IsNew was true but should have been false.");
  16:      }
  17:      finally
  18:      {
  19:        helper.Rollback();
  20:      }
  21:    }
  22:  }

The difference between this code and the code you would normally use is that you wouldn't manage your own helper and you'd call customer.Save(), not customer.Save(helper). If you dig into the guts of Save() with no parameter, you'll see it does essentially what I'm doing here. It creates a SqlHelper and opens the transaction. The difference is that if the insert works, the transaction is committed, and here the transaction is always rolled back, ensuring that the database isn't affected and leaving it in a known state for other tests.

I'm still new to automated testing, but it definitely does make being able to change existing code much easier and give me more confidence when I am doing that. And seeing all of the green lights in NUnit feels pretty good too.

Oh - the NuSoft Framework has a logo now (the one at the top of this post). What do you think of it?

Categories: Development, C#, RCM Technologies