Archive for unit testing

A Dependency Injection example with Spring.NET

As requested, here is a real world example of how I used dependency injection to simplify a project, increase modularity, and subsequently increase testability.

Here’s the project. I have a successful website called SimpleTracking.com which allows you to track packages using a simple, common user interface. It also allows you to track pages using RSS.

Here is a list of features:

  • Supports multiple shippers, including FedEx, DHL, and USPS. The tracking number is resolved to one of them, and if a tracking number could belong to more than one, they are called simultaneously, and the one that returns the results is used.
  • Results are cached to avoid overusing the shippers servers
  • Errors are handled appropriately

I boiled the design into a tree of classes:

 image

To greatly simply the design, I decided that each module would implement a common interface. After all, they all take in a tracking number, and return tracking data. Here is the ITracker interface:

public interface ITracker
{
	TrackingData GetTrackingData(string trackingNumber);
}

Simple enough? Every class in the diagram above implements the same interface. If I want to add additional functionality, such as logging for example, I can simply add a class to the chain, and implement the same interface.

Now I can wire it up with Spring.NET:

<object name="postUtility" type="YTech.ShipperInterface.Tracking.Http.PostUtility, YTech.ShipperInterface" />

<!-- The trackers that actually do the work -->
<object name="uspsTracker" type="YTech.ShipperInterface.Usps.Tracking.UspsTracker, YTech.ShipperInterface">
	<constructor-arg ref="postUtility" />
	<!-- Code removed for readability... -->
</object>
<object name="fedexTracker" type="YTech.ShipperInterface.FedEx.Tracking.FedexTracker, YTech.ShipperInterface">
	<constructor-arg ref="postUtility" />
	<!-- Code removed for readability... -->
</object>
<object name="dhlTracker" type="YTech.ShipperInterface.Dhl.Tracking.DhlScreenScrapeTracker, YTech.ShipperInterface">
	<constructor-arg ref="postUtility" />
</object>
<object name="simulationTracker" type="YTech.ShipperInterface.Tracking.Simulation.SimulationTracker, YTech.ShipperInterface" />

<!-- Combine all of the other trackers into one stream -->
<object name="multiTracker" type="YTech.ShipperInterface.Tracking.MultiTracker, YTech.ShipperInterface">
	<constructor-arg>
		<list element-type="YTech.ShipperInterface.Tracking.ITracker, YTech.ShipperInterface">
			<ref object="simulationTracker" />
			<!-- Order these by popularity -->
			<ref object="fedexTracker" />
			<ref object="uspsTracker" />
			<ref object="dhlTracker" />
		</list>
	</constructor-arg>
</object>

<!-- Cache the upstream tracking data -->
<object name="cacheTracker" type="YTech.ShipperInterface.Tracking.CacheTracker, YTech.ShipperInterface">
	<constructor-arg ref="multiTracker" />
</object>

<!-- Handle errors by logging them, and returning a special ErrorTrackingData object -->
<object name="MainTracker" type="YTech.ShipperInterface.Tracking.ErrorHandlerTracker, YTech.ShipperInterface">
	<constructor-arg ref="cacheTracker" />
</object>

Now in my code, this is all I have to do:

var ctx = ContextRegistry.GetContext();
var tracker = (ITracker)ctx.GetObject("MainTracker");
var td = tracker.GetTrackingData("my tracking number");

Every piece I’ve written is fully testable. I even created a class that posts data to a remote web server, and returns the response. This allows me to completely test the tracker classes. They don’t care if they’re hitting against a real server, or an in memory request/response mock class.

I have nearly 100% test coverage, and making changes to the site is a breeze.

The next step is to convert the actual web project to an MVC project so that I can unit test the actual page functionality.

Hopefully I’ve given a good example of how inversion of control can be a really good thing. Have any more questions about the architecture? Feel free to leave a comment.

Note: I haven’t replaced the code on the live SimpleTracking.com site yet, but I plan on upgrading in the next couple of weeks.

Do you really need a data access layer with LINQ?

Lately I’ve been giving a lot of thought to using LINQ to access my database instead of using NHibernate. I’ve been a little confused as to how LINQ would work in a data access layer, but I’m starting to think it makes sense as a replacement to the data access layer.

This article was inspired by the Google App Engine. Using the Django framework for database access is stupidly simple. They’re able to focus on getting something done, which is good enough in a lot of cases. Not every project has to be an N-Tier enterprise application.

Primarily, I write eCommerce websites. Consider the following diagram, which gives you a rough idea of how I’ve traditionally structured my applications:

Traditional Architecture

Notice that a lot of code is being tested. The sweet side of me likes unit tests, but the wheat part of me is telling me to simplify code when possible to minimize the need for unit tests. I’ve traditionally wanted a lot of unit tests at the data access layer because it tends to be a source of a lot of issues due to it’s complexity. It’s complexity is a result of impedance mismatch.

Code that is a good candidate for unit testing:

  • Logic/utility/static functions
  • Code that will be used in a lot of places, and has a well defined contract
  • Code that needs the highest levels of reliability

Now consider what happens when we use LINQ and the ADO.NET Entity Framework. The impendence mismatch has been minimized because the entity framework has automatically written our model code to match the database. It has also been my experience that the queries that are not trivial are usually not re-used. In other words, query complexity is inversely proportional to the frequency of re-use.

The end result is that our code has been greatly simplified. Now our unit tests can focus on the business logic. We’ll actually have more time for unit testing, which should lead to more stable code where it is needed most.

Sure, our UI will contain what are basically database queries. The fact is that many pages simply need a specific set of data that will populate a drop down list for example. I know that it might give people a bad feeling (as it does to myself), but I think it’s something we need to get over. If you want to test the page, in most cases you can just run it, and see that it’s working. In conjunction with a good web testing tool, it would be easy to have high levels of reliability.

Linq Architecture

Obviously there are a lot of places where this is a bad idea. I’m certainly not condoning a complete lack of a data access layer for every application. I’m applying the 80/20 rule. Places it might not make sense, or where it’s gray:

  • A logic class that needs to make frequent, repeated database calls.
  • An application that requires a certain level of testability.
  • An application that contains some extremely common queries that may or may not be trivial.

.NET XML DataSet Generator from a SQL Query

As promised, I’ve now made the .NET XML DataSet Generator available on Google Code.

.NET XML DataSet Generator

If anyone can think of a better name for the project, please let me know! It’s really hard to convey what it actually does. On the project page, I put these basic steps, which should help make it clear:

  1. Run this program to execute a SQL statement
  2. Copy the resulting XML into a file in your .NET unit test project
  3. Embed the XML file you created
  4. In your test code, load the embedded XML, deserialize it back into a DataSet (code coming soon)

As the project matures a little bit, I’ll have better documentation. I may even whip up a video demonstration. It’s not really a fancy tool, but it does come in handy.

For example, let’s say you have a database method that returns a DataSet containing a table of blog post items. You have another method that turns that DataSet into an array of post objects. I know that you’re thinking you should normally use an OR mapper, but this is just an example, so please don’t interrupt me!. This tool lets you create a serialized DataSet that you can use in a unit test, which will reconstitute the DataSet into the exact same thing your database method would have returned. You can now pass in a snapshot of real data into the method your testing. If you ARE using an OR mapper like NHibernate, this probably won’t happen much, but when it does, this tool will come in handy.

DataSet XML serializer utility for unit testing

Quite a while ago I wanted to do some unit testing with DataSet’s and DataTable’s as input. In code, there isn’t really an easy way to generate them, especially if you want them to be a realistic subset of the real data in your database.

My solution was to build a program that acted like SQL Server’s Management Studio, but who’s output is a serialized DataSet. The resulting XML can simply be embedded into your unit test project. In your unit test, you simply deserialize the DataSet XML into a DataSet.

DataSet XML Serializer

Is anyone interested in me posting the source code and compiled EXE? I’ll have to clean it up a bit, so I wanted to see if there was enough interest, of if it’s something I’ll just keep using in-house.