Friday, July 17, 2009

Moving On

I've had some styling issues with inserting code and the like here, so I decided to move on. My blog is now on wordpress.

To follow me, please use the following feedburner URL: http://feeds.feedburner.com/erikbase

Tuesday, July 14, 2009

Compiling .NET with Rake: Some Updates and More Details

In my previous post, I described how I created a rake file to handle the building of my .NET project on Team City.  I have since updated the file with some tweaks so that I could see my unit test output in Team City.  This post will describe what I changed in the file as well as how I set up Team City.

The New Rake File

The updates I made to my file, recommended by Sean, was to create and set an environment variable that indicates whether or not Team City is building this project (as opposed to just building it locally).  This is useful because the output in Team City is much more verbose, and not really necessary when building locally.  Here’s the new file:





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33


require 'fileutils'
include FileUtils

version = 'v3.5'
compile_target = ENV.include?('target') ? ENV['target'] : 'Debug'
project = "MyProject"
framework_dir = File.join(ENV['windir'].dup, 'Microsoft.NET', 'Framework', version)
msbuild = File.join(framework_dir, 'msbuild.exe')
team_city = ENV.include?('teamcity_build') ? '/re:TeamCityExtension,Gallio.TeamCityIntegration' : ''

task :default => :build

task :build => [:compile, :test]

task :compile do
sh "#{msbuild} #{project}.sln /property:Configuration=#{compile_target}"
end

task :test do
runner = 'tools\\Gallio\\Gallio.Echo.exe'
assembly = "Test\\bin\\#{compile_target}\\MyProject.Test.dll"
sh "#{runner} #{assembly} #{team_city}"
end

desc "Rebuild"
task :rebuild do
sh "#{msbuild} #{project}.sln /t:Rebuild /property:Configuration=#{compile_target}"
end

desc "Clean"
task :clean do
sh "#{msbuild} #{project}.sln /t:Clean /property:Configuration=#{compile_target}"
end






Pastie #545608 linked directly from Pastie.






You’ll see at the top a variable named “team_city”, which checks for an environment setting (which I just called “teamcity_build”).  If this setting exists, the variable is set to the command line parameters required by Gallio to generate the correct Team City output.



One other tweak was to line 22, where I added the team_city variable to the command line execution string.



Finally, on line 9, I updated the parameter flag seen in my previous post to be “/re:” (instead of “/e:”).



Team City Setup



I’m not going to go into detail about every step in configuring Team City, but will discuss some specific settings I used on my project to get it to compile with my rake file.  The screens I will be discussing are in the Adminitration panel of the Team City UI.  Once there, you can create or edit a build configuration.  In the build configuration section, you will be presented with a screen with several tabs down the side.  It is on these screens that the settings I will describe below live.



Most settings I left as the default.  However, screen 3 allows you to set a runner.  Here I just chose Rake from the “Build runner” drop down.  The next item I set was the value in the “Rake tasks” field.  If you look at the rake file above, you will see that on line 13 I set the “build” task to be my main entry point (since it compiles the code then runs the test).  So in this text box, I simply entered “build”.  This means that when Team City calls rake in the command line, it will send in the “build” parameter as an argument.  A final setting  here, which is needed if the path to your ruby compiler is not set to the Windows “Paths” variable, is the “Ruby interpreter path”.  Simply enter the path to the ruby.exe file on your build server.



The final specific setting I added to Team City was on screen 6, where the environmental variables live.  Here, click on “Add new variable”, then enter in the value you want to use to indicate that this is a Team City build.  As I mentioned above, this the value the rake file checks to see whether or not to add the appropriate Gallio command line parameters for Team City output.  To work with the script above, my environment variable value was “env.teamcity_build”.



That’s it!  Your Team City build should now work with rake.

Thursday, July 02, 2009

Compiling .NET Projects Using Rake

Before I get into too much detail, wanted to credit Sean with doing the work on this, I just ripped what he did off. :)  I just wanted to document the basics of getting a build script written using Rake that can compile your solution and run your unit tests locally.

We have it running on Team City as well, and I'll blog more about that as I learn it. :)  It does support it out of the box.

The rakefile

First thing you need to do, of course, is intall Ruby, RubyGems, and then the rake gem. Some links on this are below.

Next, in your project, create a text file and name it rakefile.rb.  In my example, I placed this in my project root (at the same level as all of my .NET project folders and solution file).  What I’m doing with rake here is having it compile my solution, and run my tests using Gallio.Echo (the command line runner for MbUnit).  It compiles the solution by passing in the correct params to msbuild.

   1: require 'fileutils'



   2: include FileUtils



   3:  



   4: version = 'v3.5'



   5: compile_target = ENV.include?('target') ? ENV['target'] : 'Debug'



   6: project = "MyProject"



   7: framework_dir = File.join(ENV['windir'].dup, 'Microsoft.NET', 'Framework', version)



   8: msbuild = File.join(framework_dir, 'msbuild.exe')



   9:  



  10: task :default => :build



  11:  



  12: task :build => [:compile, :test] 



  13:  



  14: task :compile do



  15:     sh "#{msbuild} #{project}.sln /property:Configuration=#{compile_target}"



  16: end



  17:  



  18: task :test do



  19:     runner = 'tools\\Gallio\\Gallio.Echo.exe'



  20:     assembly = "Test\\bin\\#{compile_target}\\MyProject.Test.dll"



  21:     extension = '' #'/e:TeamCityExtension,Gallio.TeamCityIntegration'



  22:     sh "#{runner} #{assembly} #{extension}"



  23: end



  24:  



  25: desc "Rebuild"



  26: task :rebuild do



  27:   sh "#{msbuild} #{project}.sln /t:Rebuild /property:Configuration=#{compile_target}"



  28: end



  29:  



  30: desc "Clean"



  31: task :clean do



  32:   sh "#{msbuild} #{project}.sln /t:Clean /property:Configuration=#{compile_target}"



  33: end




So the first part of the file allows us to set the environment variable containing target info.  Here we default to Debug if nothing is set.



Then we set up a default task, which allows us to just type in “rake” in the command line without passing parameters (on line 10).  This means we default to the “build” task.  The following line then set up dependencies on that task, and indicated that when we call build, we want to run the compile and test tasks.



The compile task simply passes in the appropriate info to msbuild.exe.  The test task simply passes in the correct parameters to Gallio.Echo.exe to run our tests.



That’s really it.  As you can see, rake isn’t doing much but delegating to different applications, but if your builds are more complex, it can definitely help manage things (like loops, etc) if they are necessary in your build script.



Resources



Download ruby: ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.8.7-p72-i386-mswin32.zip


RubyGems: http://rubyforge.org/frs/?group_id=126


Building with Rake: http://testdrivendevelopment.wordpress.com/2009/02/01/nant-sucks-and-rake-rocks/

Wednesday, July 01, 2009

“Controllerless” MVC: A high-level overview of my attempt

So there has been a lot of talk recently about doing away with controllers in MVC. My first read of it was from when Brian first mentioned it. The concept didn’t gain much traction until the discussion was renewed by Chad Myers’ post, which was then followed up by another post from Brian and then Jeffrey Palermo’s post. Phew! In any case, the basic concept is to map a request to one or more commands that are relevant for that request. The purpose of the command is simply to return data, that’s it. It should have no knowledge of anything regarding the request (no Context, no Request or Response objects).

I liked the idea but didn’t have a chance to work on it, until now. I have a new project I’m starting up at work and thought it would be a good chance to try my hand at seeing how I could implement this sort of framework.

Why I Don’t Like Controllers

Part of my current job is upgrading some existing sites to use the ASP.NET MVC framework. As I was doing this, one thing kept bugging me: the controller was doing too much! Not only did I have to retrieve data, but I also had to know how to validate it, save it, redirect to the appropriate view if necessary, etc. Since one controller had to manage every action on a single page, it quickly became large. Frankly, I felt like we were moving back towards the web forms code-behind model, where everything the page needed was in its code-behind.

The other aspect I didn’t like about how the framework worked (out of the box) was that, even when using partials, the main page still needed to contain all of the data so that it could send the correct model to any partials that implemented it. This didn’t feel right to me. At least when I did Model-View-Presenter in web forms I could have user controls that contained their own presenter, so that the containing page really didn’t need to know anything about what the controls were doing, or what data they needed. This was a step back, in my opinion.

So Why Did I Do What I Did

From Scratch vs. Utilizing ASP.NET MVC
What I am currently doing on my new project is attempting to implement the concept above (one request to one or more commands). I was torn between starting from scratch, or building it on top of the existing ASP.NET MVC framework. I decided to do the latter, as I thought the MVC framework was extensible enough to plug in my command implementation, and it also kept me from having to reinvent the wheel (ex: rendering the correct view, routing, etc).

The basic concept is I implemented was to create a single controller (utilizing the front controller pattern) that handled all requests. This would then find and call “Execute” on the correct commands. Finally, the value returned from the Execute method would be loaded to the ViewDataDictionary.

I also liked the idea of building on top of the MVC framework because it will make it simpler down the line for me to upgrade our existing projects to use this new approach, should we decide to.

Why Not Use Existing Ideas?
The first answer to this is because I thought this would be fun. :) The second is none that are out there didn’t quite meet the need, as I saw it. For example:

  • FubuMVC still revolves around a controller.
  • Jeffrey Palermo’s spike (linked above) simply limits a controller to one action, definitely better but not quite there.
  • Subcontrollers (via MvcContrib) require passing in the parent controller as a parameter to the action – eek! I definitely don’t want to be coupling controllers like that.

So How Did I Do It

Before I go into too much detail, a word of warning: nothing of what you see here is anywhere near production ready. My hope was to get some ideas out there and let people go from there (or, if my ideas suck, now they know what not to do).

Now that that’s out of the way, here are some notes on what I did. The code below is purposely incomplete, as I’m still developing this. As it gets more mature I will put it all on Google code to be downloadable, but not just yet.

The Controller and Controller Factory

As I mentioned above, the ASP.NET MVC framework is pretty extensible, so you can create your own custom versions of many of the classes it uses under the covers to work. The first thing I did was to create my own controller factory. Its main purpose in life is simply to create my front controller. It can also do one other thing, but that is outside of the scope of this high level post. In any case, here’s my factory:

   1: public class ConfigControllerFactory : CommandControllerFactory


   2: {


   3:     public override IController CreateController(RequestContext requestContext, string controllerName)


   4:     {


   5:         var commandController = new ConfigController();


   6:         return commandController;


   7:     }


   8: }


You’ll notice that it extends the CommandControllerFactory class (an abstract class with one method that I won’t get into now). You can also see that all it’s doing is returning my front controller. Here’s that controller:



   1: public class ConfigController : CommandController


   2: {


   3:     public override Type[] CommandTypes


   4:     {


   5:         get { return typeof (MyCommand).Assembly.GetTypes(); }


   6:     }


   7: }


This also implements an abstract class, CommandController, which does all of the magic (I’ll show more of it later). The purpose of this controller’s implementation is to pass to my abstract controller all commands that exist in my system.



So theoretically by implementing these two abstract classes, your web app can now use this framework. That is of course, after some additions to the global.asax.



Global.asax Changes



The first thing I changed is the default route data. Since we no longer are using controllers, I didn’t like the idea of having {controller}/{action} in my route. The MVC framework uses the controller value to find the controller, so it’s moot now anyway. So I changed my route to be the following:



   1: routes.MapRoute(


   2:     "Default",                                              // Route name


   3:     "{context}/{action}/{id}",                           // URL with parameters


   4:     new { controller = "Command", action = "DefaultAction", id = "" }  // Parameter defaults


   5: );


I liked the idea of “context” and “action” because it better showed how the commands are grouped. We have a context (like an account) and an action (saving a new account). Yeah it’s a rip-off of the BDD naming style, but I felt it was appropriate.



The other thing I had to add to the global.asax was to set the MVC framework up to use the correct factory. I did this by adding this to Application_Start:



   1: // Tell the MVC framework to use the CommandControllerFactory to create controllers.


   2: ControllerBuilder.Current.SetControllerFactory(typeof(ConfigControllerFactory));


That’s it!



The CommandController



This class is where the magic happens. Again, it’s early on (and therefore not very clean), so forgive the code. It is simply here as a reference, not as a production ready “copy and pastable” class.



The CommandController inherits from the MVC framework’s Controller class and overrides two methods: ViewResult and ExecuteCore.



ExecuteCore is where the request first comes in. At a high level, we get the context and action from the route data object, and from that we generate a unique key, which lets us map a request to the appropriate commands. Here are the simple properties:



   1: private string Context


   2: {


   3:     get { return RouteData.GetRequiredString("context"); }


   4: }


   5:  


   6: private string Action


   7: {


   8:     get { return RouteData.GetRequiredString("action"); }


   9: }


  10:  


  11: private string ContextActionKey


  12: {


  13:     get { return string.Format(NamespaceFormat, Context.ToLower(), Action.ToLower()); }


  14: }


Now that we have that key, the ExecuteCore method simply loops through all of the actions, and executes any that contain that key in their namespace. This is the link between a request and its associated actions. That way a request can execute any number of relevant actions. Here’s the loop:



   1: foreach (var commandType in CommandTypes)


   2: {


   3:     // If it's a command, execute it


   4:     if (typeof(ICommand).IsAssignableFrom(commandType) && !commandType.IsInterface)


   5:     {


   6:         // Ensure the command is in the correct namespace for the view - we only want to execute commands related to the current view


   7:         if (commandType.Namespace.ToLower().Contains(ContextActionKey))


   8:         {


   9:             var commandObject = IoC.Resolve(commandType) as ICommand;


  10:  


  11:             // Add result to ViewData if one was returned


  12:             ExecuteCommandAndLoadResultToViewData(commandObject);


  13:         }


  14:     }


  15: }


And here’s how we store whatever is returned from the command’s Execute method call:



   1: result = commandToExecute.Execute();


   2: if (result != null)


   3: {


   4:     try


   5:     {


   6:         ViewData.Add(result.GetType().FullName, result);


   7:     }


   8:     catch (ArgumentException)


   9:     {


  10:         throw new ArgumentException(string.Format("The type: {0} has already been added to the ViewData collection", result.GetType().Name));


  11:     }


  12: }


So the basic concept is each model is a unique entry into the ViewDataDictionary (for better or worse). This allowed me to create generic base classes for all of my views to inherit from. Basically it’s a class that takes a generic type. The view inherits from this class, passing in the model it expects as the generic type. Then the class retrieves the model object from the ViewDataDictionary. This means my views are now independent of the commands, they only know what model to look for in the dictionary. This also means I can create truly independent partials, since they do not rely on models being passed into them.



Summary



So there’s a lot more I didn’t touch on (like how to load an object from the view model, so that the command can use it). That will be coming up in my next posts. I’m just hoping this whets your appetite, and also generates feedback to improve this functionality.

Saturday, April 18, 2009

Philly .NET Code Camp Notes

So this Saturday I had the fortune of giving a presentation on design patterns at the Philly .NET code camp. I think there's definitely room for improvement, but overall I think it went ok.

Per some people's request, here is the link to my code repository (hosted on Google code): http://design-patterns-demo.googlecode.com/svn/trunk/

This includes both the slides and the complete source code.

Wednesday, April 15, 2009

Mapping a Generic List to a List of SelectListItems

One thing I came across several times on my current project is converting a list of items to a list of SelectListItems in order to bind them to an MVC drop down list.  In the interest of making this task easy (and to keep from repeating code), I decided to create an extension method that uses Func<T,R> and Predicate<T> parameters so that it can be used with any list of objects.

The Code

Here is the extension method:

   1: /// <summary>


   2: /// Maps generic list of items to a list of SelectListItems for use in a drop down list.


   3: /// </summary>


   4: /// <typeparam name="T">Object which is being converted to a SelectListItem</typeparam>


   5: /// <param name="itemsToMap">List of objects to map to a list of SelectListItems</param>


   6: /// <param name="textProperty">Property on the object being mapped whose value should be placed in the Text property of the SelectListItem</param>


   7: /// <param name="valueProperty">Property on the object being mapped whose value should be placed in the Value property of the SelectListItem</param>


   8: /// <param name="isSelected">Condition indicating if the current SelectListItem should have Selected set to true</param>


   9: /// <returns>List of SelectListItems</returns>


  10: public static IList<SelectListItem> MapListToListOfSelectItems<T>(this IList<T> itemsToMap, Func<T, string> textProperty, Func<T, string> valueProperty, Predicate<T> isSelected)


  11: {


  12:     IList<SelectListItem> selectListItems = new List<SelectListItem>();


  13:  


  14:     foreach (var item in itemsToMap)


  15:     {


  16:         SelectListItem selectListItem = new SelectListItem();


  17:         selectListItem.Value = valueProperty(item);


  18:         selectListItem.Text = textProperty(item);


  19:         selectListItem.Selected = isSelected(item);


  20:         selectListItems.Add(selectListItem);


  21:     }


  22:     return selectListItems;


  23: }




How it Works



As you can see, this code can work with any list of items by using lambdas to retrieve the appropriate property values.  A SelectListItem requires three properties to be filled in, the text string, the value, and whether or not it should be set to selected in the list it is bound to.  Extension methods require the first parameter to be the class that is being extended, so in this case we’re extending any IList<T> object to have this functionality.



The second parameter (textProperty) is a lambda that points to the property in the object being mapped that contains the value we want to put in the Text property of the SelectListItem.  Inside the foreach loop, the line “selectListItem.Text = textProperty(item)” is doing this work, by retrieving the value from the given property on “item”.



The third parameter (valueProperty) is similar.  It gets the value from the supplied property and passes it to the Value property on the SelectListItem.



The final parameter (isSelected) is a Predicate, which means any function that returns a boolean value.  In this case, we want to be able to pass in to this method the criteria that will indicate whether or not this SelectListItem should be selected when the list is bound.



Seeing it in Action



So here’s an example of how to use this extension method.  In this example, we will have a simple Person class, which simply has a Name and Id.  Now, our functionality needs to return a list of Persons that have been mapped so that we can bind them to a drop down list.  The other requirement is, if we’re editing a person, we want them selected by default.



Here’s the Person class:





   1: public class Person


   2: {


   3:     public string Name { get; set; }


   4:     public int Id { get; set; }


   5: }




Now we’ll have a method that does the mapping.  It will take in the list of Persons to map as well as the Id of the person being edited (so that we can determine if it should be selected in the list).





   1: private IList<SelectListItem> MapPeopleToSelectListItems(IList<Person> peopleToMap, int idOfPersonBeingEdited)


   2: {


   3:     return peopleToMap.MapListToListOfSelectItems(x => x.Name, x => x.Id.ToString(), x => x.Id == idOfPersonBeingEdited);


   4: }




So in this example, we’re simply setting the Name of the person object to the Text property of the SelectListItem, the Id of the person is the Value, and the current SelectListItem should be selected if the Id of the person is equal to the Id of the person being edited.



This has been a handy little method that hopefully is useful to you as well.

Monday, March 09, 2009

(Almost) Frictionless Testing: Integration

In my previous post, I discussed how one impediment to adopting TDD (or testing in general) is running into a series of headaches in attempting to write a test.  Once a large amount of friction is encountered, testing will be thrown out the window.  This is true either because the programmer gets frustrated, or the schedule dictates swift completion of code, and it is thought that skipping the writing of tests will speed things up.

A while ago I wrote a post on how to simplify integration tests, and the basic principles I mentioned there still stand for me:

My personal requirements that I believe make setting up an integration test relatively simple and effective … [are] the following:

  1. The ability to pass sample data into a method so that you can write tests against it
  2. The ability to allow data that you don’t care about to be dynamically generated behind the scenes so that you don’t have to worry about it
  3. The data generated by the tests should be easy to clean up so that the database is left in a clean state

Tests for Mappings

In light of that, I decided to update what I’ve learned since then and show my new code that I believe makes our tests a bit simpler to write.  Specifically, I attempted to address one concern we had, and that was how to simply test our NHibernate mappings.  In our code base, we are using the DAO model (for now anyway) and our NHibernate objects are our domain objects.

To start, I began with a base test class that took in the domain object being mapped, as well as its associated DAO.  I then noticed we had some simple classes that did not have their own DAO, so I created another test class that simply took in the domain object itself.  The first test class (with the DAO) then inherits from this test class just so that we have our shared code in one spot.  In any case, let’s see how the base classes take care of my three self-imposed requirements discussed up above.

Passing in Sample Data
There are many cases when you want to have some sort of control over the data you want to save to the data store during your integration test.  For example, if object A depends on object B, you will want to be able to persist B before setting up and writing tests for A.  To do this, I have the following methods in my base class:

   1: /// <summary>


   2: /// Saves test objects to the database before setting up the system under test.  Used if the system under test


   3: /// depends on other objects existing before it can be created.


   4: /// </summary>


   5: /// <param name="objectsToSave">Set of objects to save before setting up the system under test.</param>


   6: protected virtual void SaveDependentObjectsNeededBySystemUnderTest(params object[] objectsToSave)


   7: {


   8:     foreach (var testObject in objectsToSave)


   9:     {


  10:         _manager.GetSession().Save(testObject);


  11:     }


  12: }


  13:  


  14: /// <summary>


  15: /// Virtual method used to set up test values on the system under test when the values inserted via reflect are not sufficient.  Also


  16: /// optionally will save any objects needed to correctly set up the system under test.


  17: /// </summary>


  18: protected virtual void SetUpTestDataOnSystemUnderTest()


  19: {


  20:     SaveDependentObjectsNeededBySystemUnderTest();


  21: }




As you can see, they’re both virtual, because only some tests might need to override them.  Also, they have two different purposes.  The first one saves dependent objects, the second one by default calls the first one, but can also be overridden to set up additional values on the test object.



Note that _manager is simply an instance of the NHibernateSessionManager class.



Now that we have these methods, simply call the second one in the base class’ SetUp method:





   1: [TestFixtureSetUp]


   2: public void BaseSetup()


   3: {


   4:     SaveTestDataForSystemUnderTest();


   5: }




Dynamically Generating Data

Now, the next thing we want to do is to be able to dynamically generate data behind the scenes.  This removes the need for us to set every property on the system under test each time we want to write a new test.  The simplest way of doing this, IMHO, was simply using reflection.  So my base test class takes in an instance of a class I named ReflectiveMapper, whose only purpose in life is to set values on object properties.  Here’s the class:





   1: /// <summary>


   2: /// Class used by tests to loop through the properties of an object and set each property equal to random test data, based on the


   3: /// property's type.


   4: /// </summary>


   5: public class ReflectiveMapper


   6: {


   7:     private object itemUnderTest;


   8:  


   9:     public SystemUnderTest LoadObjectUsingReflection<SystemUnderTest>()


  10:     {


  11:         itemUnderTest = Activator.CreateInstance(typeof(SystemUnderTest));


  12:         PropertyInfo[] properties = itemUnderTest.GetType().GetProperties();


  13:         foreach (var propertyInfo in properties)


  14:         {


  15:             LoadPropertyWithTestValue(propertyInfo);


  16:         }


  17:         return (SystemUnderTest)itemUnderTest;


  18:     }


  19:  


  20:     private void LoadPropertyWithTestValue(PropertyInfo propertyInfo)


  21:     {


  22:         if (propertyInfo.CanWrite)


  23:         {


  24:             propertyInfo.SetValue(itemUnderTest, CreateTestValueBasedOnPropertyNameAndType(propertyInfo), null);


  25:         }


  26:     }


  27:  


  28:     private object CreateTestValueBasedOnPropertyNameAndType(PropertyInfo propertyInfo)


  29:     {


  30:         Type propertyType = propertyInfo.PropertyType;


  31:         object testValueToReturn = null;


  32:  


  33:         if (propertyType == typeof(string))


  34:         {


  35:             testValueToReturn = GenerateRandomString();


  36:         }


  37:         else if (propertyType == typeof(int))


  38:         {


  39:             testValueToReturn = GenerateRandomInteger();


  40:         }


  41:         else if (propertyType == typeof(DateTime))


  42:         {


  43:             testValueToReturn = DateTime.Now;


  44:         }


  45:         else if (propertyType == typeof(Guid))


  46:         {


  47:             testValueToReturn = Guid.NewGuid();


  48:         }


  49:         else if (propertyType == typeof(bool))


  50:         {


  51:             testValueToReturn = true;


  52:         }


  53:  


  54:         return testValueToReturn;


  55:     }


  56:  


  57:     private int GenerateRandomInteger()


  58:     {


  59:         return new Random().Next(1000);


  60:     }


  61:  


  62:     private string GenerateRandomString()


  63:     {


  64:         return new Random().Next(999).ToString();


  65:     }


  66:  


  67:     public void SetField(object target, string fieldName, object value)


  68:     {


  69:         FieldInfo fi = target.GetType().GetField(fieldName, BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance);


  70:         fi.SetValue(target, value);


  71:     }


  72:  


  73:     public void SetIdField(object target, string fieldName, int value)


  74:     {


  75:         SetField(target, fieldName, value);


  76:     }


  77: }




First, you’ll see that it take in a generic object, so that we can reflectively load any object.  It creates an instance of it, then loads each property using the correct value associated with its type.  You’ll see that for strings and ints, I used a little trickery.  To ensure a random int, I used the built-in Random class.  However, I also wanted somewhat random strings, so I figured the easiest way to do that was simply string-ify the random ints.  That way different string and int properties are (for the most part) set with different values, which I like.



Another thing this class does is allows you to set values on properties with no setters (useful for setting IDs, which should never contain a setter, since we want NHibernate to load them, not our code).



Leaving the Database in a Known State

There are two ways that I’ve used to clean up databases after integration tests.  The first way I did it was using transactions.  The pro of this is that you don’t have to remember to delete your data once your test is complete.  The con is you have to make sure your test database has all expected tables and constraints set up before the test is run.



The second way you can do this is by running scripts.  Since the codebase I came into already had set up and tear down scripts in place, I saw no reason to change this, so that is what I’m using currently.  The pro is that the database is in a known state both before and after the tests are run.  The con is you have to manually update these scripts each time you create, update, or delete any tables in your system.



To run the scripts, we first have two .SQL files in our project, one for creating objects, another for tearing them down (basically just dropping everything in the system).  To run these scripts, we have a ScriptRunner class, which has two methods which I’ll show below.  Just for full disclosure, my co-worker Sean wrote this code, not me, so I can’t take credit for it. :)





   1: /// <summary>


   2: /// Class containing the functionality to run set up and tear down scripts for mapping tests.


   3: /// </summary>


   4: public class ScriptRunner


   5: {


   6:     private readonly string connectionString;


   7:     private const string SetupFile = @"Files\CreateObjects.sql";


   8:     private const string TearDownFile = @"Files\DropObjects.sql";


   9:  


  10:     public ScriptRunner(string connectionString)


  11:     {


  12:         this.connectionString = connectionString;


  13:     }


  14:  


  15:     public void RunSetUpFile()


  16:     {


  17:         SqlScriptRunner runner = new SqlScriptRunner(GetCommandText(SetupFile));


  18:         using (SqlConnection conn = new SqlConnection(connectionString))


  19:         {


  20:             conn.Open();


  21:             using (SqlTransaction trans = conn.BeginTransaction())


  22:             {


  23:                 runner.Execute(trans);


  24:                 trans.Commit();


  25:             }


  26:         }


  27:     }


  28:  


  29:     public void RunTearDownFile()


  30:     {


  31:         SqlScriptRunner runner = new SqlScriptRunner(GetCommandText(TearDownFile));


  32:         using (SqlConnection conn = new SqlConnection(connectionString))


  33:         {


  34:             conn.Open();


  35:             using (SqlTransaction trans = conn.BeginTransaction())


  36:             {


  37:                 runner.Execute(trans);


  38:                 trans.Commit();


  39:             }


  40:         }


  41:     }


  42:  


  43:     private string GetCommandText(string fileName)


  44:     {


  45:         string command;


  46:         using (FileStream fs = new FileStream(MakeFullPath(fileName), FileMode.Open, FileAccess.Read))


  47:         using (StreamReader sr = new StreamReader(fs))


  48:         {


  49:             command = sr.ReadToEnd();


  50:         }


  51:         return command;


  52:  


  53:     }


  54:  


  55:     private string MakeFullPath(string fileName)


  56:     {


  57:         string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", ""));


  58:         assemblyPath = System.Text.RegularExpressions.Regex.Replace(assemblyPath, @"bin\\.*", "");


  59:         return Path.Combine(assemblyPath, fileName);


  60:     }


  61: }




Of course there are other ways of setting up your databases for integration tests, including generating them in-memory from your NHibernate mapping files.  The purpose of what I’m showing you here is just to give you one example of how it can be done.



Comparing Values


Now, if you’re testing mapping, you want to ensure that the value in your object is the same value that was persisted to the database.  To do this, we went the route of having an object persisted, then doing a simple ADO query to retrieve a DataRow, and finally checking the values in that row and comparing them to the values in our object.  This is done by a method on our base class, which returns a ValueChecker object, which has the duty of comparing the values to see if they are equal (this also allows us to do a kind of fluid interface).  Here’s the method call along with the call to get the DataRow:





   1: protected ValueChecker EnsureThat(object valueToCheck)


   2: {


   3:     GetDataRowWithTestData();


   4:     return new ValueChecker(testDataRow, valueToCheck);            


   5: }


   6:  


   7: private void GetDataRowWithTestData()


   8: {


   9:     if (testDataRow == null)


  10:     {


  11:         SqlConnection conn = new SqlConnection(ExtractConnectionString());


  12:         SqlCommand cmd = new SqlCommand(SqlToRetrieveTestDataRow, conn);


  13:         cmd.CommandType = CommandType.Text;


  14:         SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd);


  15:         conn.Open();


  16:         try


  17:         {


  18:             DataSet ds = new DataSet();


  19:             dataAdapter.Fill(ds);


  20:             testDataRow = ds.Tables[0].Rows[0];


  21:         }


  22:         finally


  23:         {


  24:             conn.Close();


  25:         }


  26:     }


  27: }  




You can see a put a class-level row DataRow variable and check if it’s null, so that I’m not hitting the database on every test in the fixture.  Next, here’s the simple ValueChecker class:





   1: public class ValueChecker


   2: {


   3:     private readonly DataRow dataRow;


   4:     private readonly object valueToCheck;


   5:  


   6:     public ValueChecker(DataRow dataRow, object valueToCheck)


   7:     {


   8:         this.dataRow = dataRow;


   9:         this.valueToCheck = valueToCheck;


  10:     }


  11:  


  12:     public void IsEqualToValueInColumnWithName(string columnName)


  13:     {


  14:         bool valuesAreEqual = (dataRow[columnName].ToString() == valueToCheck.ToString());


  15:         Assert.IsTrue(valuesAreEqual, string.Format("Values are not equal: Column name: {0}, Value 1: {1}, Value 2: {2}", columnName, dataRow[columnName], valueToCheck));


  16:     }


  17: }




The simplest way I found with the data I’m generating to see if the values are equal is to simply convert them to strings.  So far, it’s working great.  In any case, with the base class method and the ValueChecker class in place, test code could look something like:





   1: [TestFixture]


   2: public class When_mapping_a_company : MappingTestFor<Company, CompanyDao>


   3: {


   4:     [Test]


   5:     public void The_value_in_the_id_property_should_be_equal_to_the_value_in_the_ncompanyid_column()


   6:     {


   7:         EnsureValueIn(x => x.Id).IsEqualToValueInColumnWithName("nCompanyId");


   8:     }


   9: }




Finally, there is one final piece to getting this to work.  For each test fixture, we need the SQL to return the sample DataRow to test against.  For different tests, this could be different data, so for now we simply put an abstract property on the base class:





   1: protected abstract string SqlToRetrieveTestDataRow { get; }




Each test fixture then overrides this.  Using an example from the Company test above, it would look something like:





   1: protected override string SqlToRetrieveTestDataRow


   2: {


   3:     get { return string.Format("select * from dbo.Company where nCompanyId = {0}", systemUnderTest.Id); }


   4: }




The systenUnderTest object is automatically set up in the base class (via reflection, as mentioned above, as well as any data supplied in the overridden virtual methods, discussed earlier) and then saved, so there’s no need to define it or set it up elsewhere.



As always, I’m open for feedback on more improvements we can add to this test base.