Yesterday, my team had a developer forum session to assist one our own get our latest release to build on our build server from a new branch. He had been working on it for a couple days and was getting nowhere. He would follow our documented process to create the new build and when he got to the end of it the build threw the following error:

The path C:\Build\ProductReleases\FullBuildv5.4.2x\Sources is already mapped to workspace BuildServer_23.

We used the Team Explorer IDE and attempted to identify this rogue workspace. Try as we might we couldn't locate it. We tried deleting all the source code on the file system. We tried nuking all the workspaces we could see through the IDE.

In the end we had seven developers in a room shouting out ideas to a frustrated developer sitting the keyboard. So we broke for lunch.

After lunch, I returned to my desk to troll the MSDN Team Foundation Server Developer Center. Using the tf workspaces command, you can get a list of all the workspaces you have created:

C:\>tf workspaces

Server: BuildServer
Workspace Owner          Computer Comment
--------- -------------- -------- --------
BOBBY     work\Bobby 	 BOBBY

But if you add the owner switch, you can get a list of all the workspaces on the server:

C:\>tf workspaces /owner:*

Server: BuildServer
Workspace      Owner      Computer  Comment
-----------    ---------- --------- -------------------------------
BuildServer    Shane      BuildServer
BuildServer    Craig      BuildServer
BuildServer    TFSSETUP   BuildServer
BuildServer    Keith      BuildServer
BuildServer_1  TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_10 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_12 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_13 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_14 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_16 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_2  TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_23 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_28 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_3  TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_30 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_31 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_32 TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_4  TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_6  TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_7  TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_8  TFSSERVICE BuildServer  Workspace created by Team Build
BuildServer_9  TFSSERVICE BuildServer  Workspace created by Team Build

From this output we can see that our build service user TFSSERVICE has a lot of workspaces defined. Considering we have 3 builds so far. Something is very wrong here.

Our original error message referenced a workspace named BuildServer_23 which does show up in our list. Using the tf workspace command, we can completely remove the workspace:

C:\>tf workspace /delete /server:BuildServer BuildServer_23;TFSSERVICE
A deleted workspace cannot be recovered.
Workspace 'BuildServer_23;TFSSERVICE' on server 'BuildServer' has 0 pending change(s).
Are you sure you want to delete the workspace? (Yes/No) Y

Our build now runs as expected. It's now time to verify what all those other workspaces are and remove them if they are not needed.

Hope this helps someone out there if you are desparately googling for away around this error.


 
Categories: Development | Tools

The application I am currently working on has a hand rolled implementation of Ajax that is somewhat awkward to work with. At the end of our last sprint, I was tasked with spiking what it would take to migrate to the .NET Ajax 1.0 extensions while everyone else was working on release week tasks.

It took a couple days to figure out all the installs, web.config modifications, component vendor compatibility and other various things. But in the end, I had a simple page with two sample Ajaxified controls that worked.

I then turned to the task of unraveling the way the current implementation was wired up and modifying a single page to use the Ajax framework instead. A few minor safe refactorings and quirks later, I had a semi-functional reference implementation with one giant problem.

The page contained a series of drop down lists that filter each other as you make selections. On initial page load, I could select an item any drop down and it would appropriately modify the others. The second selection always returned the following error:

Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned was: 404

Reguardless of what list I selected from first, the second request would fail. My IIS logs revealed that my request was being sent to server, but for whatever reason the URL changed.

2008-10-17 14:52:14 W3SVC1 127.0.0.1 POST /Aware/Xtend/mParticipant/NewPlannedService.aspx  80 - 127.0.0.1 200 0 0

2008-10-17 14:52:20 W3SVC1 127.0.0.1 POST /Aware/mParticipant/NewPlannedService.aspx  80 - 127.0.0.1 404 0 0

Using Fiddler, I was able to see that a value for formAction was being sent back to the client that was invalid. You can also see that the second request is going to a non-existent page:

FiddlerOutPut

I was able to resolve the issue by explicitly setting the value of my forms action back to the correct path at the end of my call back method like so:

this.Form1.Action = Request.Url.PathAndQuery

But this seemed like a hack in the worst way and smelled somewhat like moldy cheese to me. And I still didn't understand what was causing the issue.

The application makes extensive use of Server.Transfer as a "performance enhancement". I noticed that the form I was working with was one of these cases where Page1.aspx transfers execution to my Ajaxified page.

I decided to try to isolate the behavior and reproduce it in a simple example project.

I fired up Visual Studio and created a new Ajax website. I added two pages; Default.aspx and AjaxPage.aspx. I implemented a simple ajax call back on my ajax page and the default page transfer execution in its Page_Load method.

To my surprise, it worked with no problems. I didn't see the nasty error at all. I verified with Fiddler. I was stumped.

I started thinking about the behavior in my application. The only difference I could think of was that the page that was being transferred to was in a different subdirectory than the original page. So I created a folder in my test project and moved AjaxPage.aspx into it. And this time I got the error. I confirmed with Fiddler that my "Folder" sub directory was being dropped off the second request and that it was missing from the response from the first request.

My smelly cheese hack worked as well for my test project. But I didn't want to solve this issue with a server side hack. So I created the following client side Javascript to hook into the client ajax framework and solve it there in a single place:

var orginalFormAction = null;

//capture the current form action value
function BeginRequestHandler() {
  orginalFormAction = theForm.action;
}

//set the form action value back to the
//correct value
function EndRequestHandler() {
  theForm.action = orginalFormAction;
  theForm._initialAction = orginalFormAction;
}

function RegisterRequestHandlers() {

  if (typeof (Sys) != "undefined") {
  
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
    Sys.Application.notifyScriptLoaded();
    
  }
}

//register request handlers after the application 
//has successfully loaded.
Sys.Application.add_load(RegisterRequestHandlers);

I can then add the script to any ajax page, by adding the following code to my Page_Load event handler:

protected void Page_Load(object sender, EventArgs e)
    {
      PageScriptManager.Scripts.Add(
        new ScriptReference("~/Script/Ajax.Server.Transfer.Fixer.js")
        );
    }

Problem solved and I didn't have to rewrite the entire application to get rid of Server.Transfer calls. On to other things.

Fiddler Tip: To get Fiddler to capture traffic when you are debugging on local host, after you hit F5 to begin degugging change the address so that localhost has a "." after it. For instance, you start debugging and the you have the following URL in the Address bar: http://localhost:49573/Default.aspx Change it to http://localhost.:49573/Default.aspx hit enter and Fidder will start picking up your traffic.


 
Categories: Development | Tools

Introduction

As you may have noticed, I have become interested in the concept of Object Relational Mapping and the NHibernate framework. One of the more painful/tedious aspects of using NHibernate is hand writing the xml mapping files. That is why I got excited when I heard that Jeremy Miller was open sourcing his mapping generation libraries.

FHLogo The Fluent NHibernate project is an effort to create a set of APIs that generate NHibernate mapping files using a fluent interface. I downloaded the source code from the Google Code Repository and quickly found myself adding fluent methods. I submitted my changes to the project and was accepted as a contributor.

One of the tasks identified by the project owner, James Gregory, was to create a quick start guide that easily fit into the NHibernate Quick Start section 1.3 Mapping the cat. I assigned the task to myself and start hacking some code.

Creating the Mapping Class

First, create a new class project QuickStart.Domain to hold  domain model objects that need to be mapped. To this assembly,  add the Cat class from the NHibernate quick start.

namespace QuickStart.Domain
{
    public class Cat
    {
        public virtual string Id { get; set; }

        public virtual string Name { get; set; }

        public virtual char Sex { get; set; }

        public virtual float Weight { get; set; }
    }
}

This is what the class looks like after a little ReSharper Code Clean Up loving.

Then add a second class project QuickStart.Domain.Mapping to hold  domain model mapping classes using the Fluent NHibernate library. Add references to both the FluentNHibernate.dll and the domain model library.

Create a new class in the mapping library called CatMap. This class will inherit from ClassMap<T> where T is the type you are creating the map for, in this case Cat. Create a constructor for the CatMap class. The constructor is where the mappings will be defined.

Because CatMap is an instance of ClassMap, you can begin using the fluent interface in the constructor right away.

public CatMap()
        {
            this.TableName = "Cat";
        }

The TableName property of the ClassMap object specifies the name of the table in the data store that stores the Cat class. This explicit setting of the table name is unnecessary. If one is not provided the API will assume the table has the same name as the class being mapped. So, for the rest of this example, it will be dropped.

The API offers several fluent methods for defining an identifier though the Id method of ClassMap. The Cat example uses the UUID generator which looks like this:

 

public CatMap()
        {           
            this.Id(x => x.Id)
                .GeneratedBy
                .UuidHex("B");
        }
 

An identity column in SQL server would be mapped like this:

public CatMap()
        {
            Id(x => x.Id);
        }

These two examples take advantage of the new C# 3.0 syntax sugar lambda expressions. An explanation of lambda expressions is outside the scope of this article, but  tons of information is available on the topic on the web.

The remainder of the CatMap constructor uses the Map method of ClassMap to define the remaining properties of the class.

public CatMap()
        {
            this.TableName = "Cat";
           
            this.Id(x => x.Id)
                .GeneratedBy
                .UuidHex("B");

            //non-nullable string with a length of 16
           this.Map(x => x.Name)
                .WithLengthOf(16)
                .CanNotBeNull();

            //simple properties
            this.Map(x => x.Sex);
            this.Map(x => x.Weight);
        }

Both the Sex and Weight properties of the Cat class are mapped quickly with a single call to them Map method. You do not need to explicitly specify the type of your properties, Fluent NHibernate will infer it based on the type being mapped. The Name property has an additional two fluent calls to limit the length of the property to sixteen characters and to disallow null values.

Usage of this mapping generates the following XML document:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
  default-lazy="false" 
  assembly="QuickStart.Domain" namespace="QuickStart.Domain">
  <class name="Cat" table="Cat" xmlns="urn:nhibernate-mapping-2.2">
    <id name="Id" column="Id" type="String" unsaved-value="0">
      <generator class="uuid.hex">
        <param name="format">B</param>
      </generator>
    </id>
    <property name="Weight" column="Weight" type="Single">
      <column name="Weight" />
    </property>
    <property name="Sex" column="Sex" type="Char">
      <column name="Sex" />
    </property>
    <property name="Name" column="Name" length="16" type="String" not-null="true">
      <column name="Name" />
    </property>
  </class>
</hibernate-mapping>

This mapping xml is a bit more verbose than the original example from the NHibernate quick start, but this post is being written using an alpha version of the Fluent NHibernate library. There is a lot of clean up and work left to be done.

Hooking It All Up

So, how exactly did I go from CatMap to generated XML document? There is currently no recommended methodology that I am aware of, but I am happy to share how I accomplished it.

I started by adding an interface to the Mapping library called IMapGenerator that looks like this:

namespace QuickStart.Domain.Mapping
{
    public interface IMapGenerator
    {
        string FileName { get; }
        XmlDocument Generate();
    }
}

 

FileName is defined in the fluent interface on the ClassMap class, I know I added it while writing this code ;). It represents the conventional name for the NHibernate mapping files. For example, We are mapping the class Cat so FirstName would contain the string "Cat.hbm.xml". Generate on the other hand, will be a wrapper around the ClassMap's CreateMapping method.

I then added the interface to the CatMap class. The final CatMap looks like this:

namespace QuickStart.Domain.Mapping
{
    public class CatMap : ClassMap<Cat>, IMapGenerator
    {
        public CatMap()
        {
             Id(x => x.Id)
                .GeneratedBy
                .UuidHex("B");

            Id(x => x.Id);

            //non-nullable string with a length of 16
            Map(x => x.Name)
                .WithLengthOf(16)
                .CanNotBeNull();

            //simple properties
            Map(x => x.Sex);
            Map(x => x.Weight);
        }
        
        public XmlDocument Generate()
        {
            return CreateMapping(new MappingVisitor());
        }
    }
}

 

I now have a way to identify all my mapping classes using the interface. I wanted to be able to automatically get a list of all the classes that implement the IMapGenerator interface, so  created a helper class GeneratorHelper with a single static method GetMapGenerators. The class lives in the Mapping library and looks like this:

namespace QuickStart.Domain.Mapping
{
    public class GeneratorHelper
    {
        private const string GENERATOR_INTERFACE = "IMapGenerator";

        public static IList<IMapGenerator> GetMapGenerators()
        {
            IList<IMapGenerator> generators = new List<IMapGenerator>();
            Assembly assembly = Assembly.GetAssembly(typeof(IMapGenerator));
            foreach (Type type in assembly.GetTypes())
            {
                if (null == type.GetInterface(GENERATOR_INTERFACE)) continue;
                var instance = Activator.CreateInstance(type) as IMapGenerator;
                if (instance != null)
                    generators.Add(instance);
            }
            return generators;
        }
    }
}

This method uses reflection to locate and load the assembly that contains the IMapGenerator interface. It then iterates over the types in the loaded assembly and checks to see if the type implements the IMapGenerator interface. If a match is found, an instance of that class is created and added to the generators list.

Finally, I created a console application, QuickStart.Domain.Mapping.Mapper, and added a reference to my Mapping library. The implementation of my console app is fairly straight forward.

 

namespace QuickStart.Domain.Mapping.Mapper
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            IList<IMapGenerator> generators =
                GeneratorHelper.GetMapGenerators();
            
            foreach (IMapGenerator generator in generators)
            {
                XmlDocument classMapXML = generator.Generate();
                classMapXML.Save(generator.FileName);
            }
        }
    }
}

 

The app calls the generator helper class to get a list of IMapGenerator objects which it then iterates over calling each objects Generate method and saves the result using the conventional name for mapping files. It works fairly well and I can add as many mapping classes as I need to the Mapping library and spin out xml any time I need.

Now where Fluent NHibernate becomes really interesting is when you decide to do away with xml mapping files all together. For a great example of this check out Zachariah Young's post, "Does the Fluent NHibernate create static XML mapping files?".


 
Categories: Development | Fluent Interface | NHibernate | Tools

At the end of yesterdays internal study group meeting, the organizer mentioned that I would be giving a presentation on NHibernate the following week. I plan to give a simple dog and pony show of persisting a simple object to the database and all of the setup needed to accomplish the task.

One of the participants asked for a brief description of NHibernate. I explained that it is an ORM framework (Object Relational Mapping). I expanded a bit by saying that NHibernate removes the dependency between your domain objects and your relational database by handling mapping from one to the other.

After a couple more questions it was determined that NHibernate generates SQL and is therefore inferior to stored procedures. It was the general feeling that stored procedures were the be all end all for performance and optimization. I attempted to explain that NHibernate generates parameterized queries which have all the advantages of cached query plans that stored procedures do. By this time the meeting was breaking up and I had a mission.

I wanted to challenge the dogmatic urban legend passed down from .NET developer to .NET developer since the classic ASP days. That dogma simply states you should always access your database via stored procedure for "performance reasons". Inline SQL is BAAAAAAD.

So I fired up Visual Studio, created a class and started writing tests.

The first thing I wanted to do was to create a baseline. I created a User table in a fresh SQLExpress database and wrote a test to pop 1000 rows into it in the crustiest "I just read my first Wrox book" way I could think of. I added some timing code and let it rip. The test looks like this:

 

       [Test]
        public void Time_Inline_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;

            using (SqlConnection c = new SqlConnection(connectionString))
            {
                c.Open();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    using (SqlCommand co = new SqlCommand())
                    {
                        co.Connection = c;
                        co.CommandText =
                            "INSERT INTO dbo.Users "
                            + "(Handle, FirstName, LastName, Password, EmailAddress, LastLogon) "
                            + "VALUES ("
                            + "'UserHandle" + i + "',"
                            + "'UserFirstName" + i + "',"
                            + "'UserLastName" + i + "',"
                            + "'UserPassword" + i + "',"
                            + "'User" + i + "@email.com',"
                            + DateTime.Now.ToShortDateString() + ")";

                        co.ExecuteNonQuery();
                    }
                }
                c.Close();
            }
            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by inline query", 
                time.TotalMilliseconds, INSERT_COUNT));
        }

From a fresh load of my test assembly into MbUnit, this code takes 1312.5 milliseconds to run 1000 inserts. Running the test repeatedly drops the time to 437.5 miliseconds. It appears that SQL Server does some optimizations for inline inserts regardless of what the tribe tells me.

Next up, I wanted to see if parameterizing the query would improve the performance. The test case looks like this:

        [Test]
        public void Time_Parameterized_Query_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;

            using (SqlConnection c = new SqlConnection(connectionString))
            {
                c.Open();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    using (SqlCommand co = new SqlCommand())
                    {
                        co.Connection = c;
                        co.CommandText =
                            "INSERT INTO dbo.Users (Handle, FirstName, LastName, Password, EmailAddress, LastLogon) VALUES (@p1,@p2,@p3,@p4,@p5,@p6)";
                        co.CommandType = System.Data.CommandType.Text;
                        co.Parameters.AddWithValue("@p1", "UserHandle" + i);
                        co.Parameters.AddWithValue("@p2", "UserFirstName" + i);
                        co.Parameters.AddWithValue("@p3", "UserLastName" + i);
                        co.Parameters.AddWithValue("@p4", "UserPassword" + i);
                        co.Parameters.AddWithValue("@p5", "User" + i + "@email.com");
                        SqlParameter param = new SqlParameter("@p6", SqlDbType.DateTime);
                        param.Value = new DateTime(2000, 1, 1);
                        co.Parameters.Add(param);

                        co.ExecuteNonQuery();

                    }
                }
                c.Close();
            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by parameterized query", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs in 1296.9 milliseconds on a fresh load of my test assembly. Repeated runs drops the test run to ~350 milliseconds a slight advantage over the inline query. I imagine this gap would widen with a more complex query.

Finally, we have the acclaimed SQL Stored Procedure dogmatic method of how everything should be done! The stored procedure in the code below is pretty much exactly what you expect it to be.

       [Test]
        public void Time_Stored_Proceedure_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;

            using (SqlConnection c = new SqlConnection(connectionString))
            {
                c.Open();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    using (SqlCommand co = new SqlCommand())
                    {
                        co.Connection = c;
                        co.CommandText = "AddUser";
                        co.CommandType = CommandType.StoredProcedure;
                        co.Parameters.AddWithValue("@p1", "UserHandle" + i);
                        co.Parameters.AddWithValue("@p2", "UserFirstName" + i);
                        co.Parameters.AddWithValue("@p3", "UserLastName" + i);
                        co.Parameters.AddWithValue("@p4", "UserPassword" + i);
                        co.Parameters.AddWithValue("@p5", "User" + i + "@email.com");
                        SqlParameter param = new SqlParameter("@p6", SqlDbType.DateTime);
                        param.Value = new DateTime(2000, 1, 1);
                        co.Parameters.Add(param);

                        co.ExecuteNonQuery();

                    }
                }
                c.Close();
            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by stored proceedure", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs unexpectedly in 1390.6ms. This seems like quite a long time for a stored procedure that is stored in the database and from my understanding with a query plan in place. Subsequent executions of the test yield execution times ~320ms. Just to verify this, I closed the MbUnit test runner application and reran these tests. I got the same results.

Now that we have a baseline of the various direct SQL methods that are well accepted in the .NET community, I want to see how NHibernate performs at these tasks. I see two methods available though NHibernate spinning up a session and cramming User objects into its Save() method and adding a transaction into the mix.

My first NHibernate test looks like this:

       [Test]
        public void Time_NHibernate_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;
            using (ISession session = factory.OpenSession())
            {
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    User u = new User();
                    u.Handle = "UserHandle" + i;
                    u.FirstName = "UserFirstName" + i;
                    u.LastName = "UserLastName" + i;
                    u.Password = "UserPassword" + i;
                    u.EmailAddress = "User" + i + "@email.com";
                    u.LastLogon = DateTime.Now;

                    session.Save(u);

                }
                session.Close();

            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by nhibernate", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs in 1656.3ms with reruns clocking in at ~560ms. It looks like NHibernate might have a slight performance hit when compared to stored procedures.

My last test using NHibernate transactions looks like this:

       [Test]
        public void Time_NHibernate_Tansaction_Inserts_To_User_Table()
        {
            DateTime start = DateTime.Now;
            using (ISession session = factory.OpenSession())
            {

                ITransaction transaction = session.BeginTransaction();
                for (int i = 0; i < INSERT_COUNT; i++)
                {
                    User u = new User();
                    u.Handle = "UserHandle" + i;
                    u.FirstName = "UserFirstName" + i;
                    u.LastName = "UserLastName" + i;
                    u.Password = "UserPassword" + i;
                    u.EmailAddress = "User" + i + "@email.com";
                    u.LastLogon = DateTime.Now;

                    session.Save(u);

                }
                transaction.Commit();
                session.Close();

            }

            DateTime end = DateTime.Now;
            TimeSpan time = end - start;

            Console.WriteLine(
                string.Format("{0} milliseconds to run {1} inserts by nhibernate with transaction", 
                    time.TotalMilliseconds, INSERT_COUNT));

        }

This test runs in 1406.3ms with follow up runs in 300ms. A dramatic increase in performance over over the non transactional processing. So the final performance test results looks something like this:

Test 1st Run nth Run
Inline SQL 1312.5ms ~430ms
Parameterized Query 1296.9ms ~350ms
Stored Procedure 1390.6ms ~320ms
NHibernate 1565.3ms ~560ms
NHibernate w/Transaction 1406.3ms ~300ms

I am not going to try to interpret these results, but simply publish them and see what feedback I get from the collective. My next steps are to increase the complexity of what I am doing; add some joins into the mix. I want to see if the performance gap widens or a clear winner emerges.

If you would like to see the entire code base for these tests, I have published them to my CodePlex repository and would love to hear your ideas on squeezing out performance with both SQL and NHibernate. Look for the NHibTester solution.


 
Categories: Performace | Tools | Unit Testing

In a recent post, I discovered a flaw in my world domination plot. I had written a Unit Test to test my expectation that the method GetByID() of the class UserRepository returned the expected User. When UserRepository.GetById() is called, it calls IDataProvider.GetById(), which returns an instance User to the UserRepository which in turn returns it to the caller.

My UserRepository class delegates database access to the interface IDataProvider. This allows me to substitute any implementation of IDataProvider to satisfy this responsibility. In non testing code I use Dependancy Injection to map UserDataProvier to IDataProvider. But in testing code I do not really want to hit a database as it slows the testing process down. So I use Rhino.Mocks instead.

Rhino.Mocks is a framework for creating mock objects for use in Unit Testing. Provide Rhino.Mocks with an Interface and it will give you back an object that implements that interface. You can also tell it to expect certain calls against the interface and how it should respond.

My Unit Test looked something like this:

      [Test]
        public void GetByIdTest()
        {
            MockRepository mock = new MockRepository();

            IDataProvider dataProvider = (IDataProvider)mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            Expect.Call(dataProvider.GetById(1)).Return(new User() { Id = 1 });

            mock.ReplayAll();
            User u = target.GetById(1);
            mock.VerifyAll();

            Assert.AreEqual(1, u.Id);
        }

As you can see this test, creates a MockRepository that is provided by the Rhino.Mocks framework. It then declares an instance of IDataProvider but delegates the creation of that instance to the MockRepository's CreateMock method. This tells Rhino.Mocks to create a dummy instance of the IDataProvider interface. Next we new up a UserRepository (the actual target of the unit test) and provide our mocked IDataProvider to it's constructor. Then we tell Rhino.Mocks to expect a call to our mock IDataProvider's GetById method and to return a new instance of User with it's Id property set to 1. Finally, we do our testing and validation.

This test fails to compile. The entity class User has read only properties. Id happens to be one of them. In the domain model for this particular application Id is a unique identifier and once a User instance is returned from the data access layer, it should never be modified.

So this presents a unique challenge, how do I test that UserRepository.GetById(1) returns an instance of User with an Id of 1?

I went down the path of trying to use Ninject (an Inversion of Control container), to inject the value in a newed up instance. But this had code smell for me. Why am I creating a dependency on Ninject to get my Unit Tests to work. That just seemed wrong to me. So I began digging in the Rhino.Mocks documentation wiki to see if it had a method for resolving this.

That was when Aiden Montgomery in the #ALT.NET IRC channel suggested that I use Reflection. He even went so far as to download my source from CodePlex and demonstrate what he was suggesting in my application.

The final test ended up looking something like this:

[Test]
        public void GetByIdTest()
        {
            MockRepository mock = new MockRepository();
            
            Type userType = typeof(User);
            PropertyInfo pi = userType.GetProperty("Id");
            User user = new User();
            pi.SetValue(user, 1, null);

            IDataProvider dataProvider = 
                (IDataProvider) mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            Expect.Call(dataProvider.GetById(1)).Return(user);

            mock.ReplayAll();
            User u = target.GetById(1);
            mock.VerifyAll();

            Assert.AreEqual(1, u.Id);
        }

 

This of course passed, didn't add a non-BCL dependency and maintained the original intent of the test and the domain model. With all the shiny new toys, I was forgetting to see the forest through the trees and return to the simplest solution. Thanks to Aiden for bringing me back down from the clouds.


 
Categories: Development | Tools | Unit Testing

Stephen Bohlen of Microdesk recently posted to the ALT.NET mailing list that he plans to release his internal training material on NHibernate to the world at large. The first two, of a planned  5, are online and ready for consumption.


I have been doing some noodling with NHibernate recently, so I downloaded the screen casts and watched them this morning. The quality is excellent, the material is comprehensive and Stephen's teaching style is top notch.

If you are interested in learning what NHibernate is all about and what you can do with it, I cannot recommend these enough. Grab them here:


 
Categories: Development | Fundamentals | Tools

I have been reading a ton of the ALT.NET bloggers and mailing list lately. They are constantly talking about the methodology of software development and the tools they use. On the concept front Domain Driven Design, Inversion of Control, Separation of Concerns and Test Driven Development are all popular topics that have been stewing in my mind. I also wanted to give some of the tools like Nhibernate, Rhino.Mocks and Ninject a try. I was also itching to get into the new Microsoft ASP.NET MVC code.

For the last couple months, I have been festering in the swamp of legacy VB.NET spaghetti code and haven't had the time or motivation to write something fresh just for the sheer joy of creation. Friday, I kind of snapped, fired up Visual Studio 2008, downloaded the tool stack and started hacking away.

Things seemed to just click on all of the topics I had been reading about. I started out with NHibernate and getting a simple User entity to persist to a SQL Sever 2005 database. I then moved on to implementing the Repository Pattern for my User entity abstracting away the actual persistence to a DataProvider class wrapping NHibernate. By this time I had Factory Patterns all over the place, so I added a reference to Ninject.Core and got rid of those too. I then whipped out a MVC site to consume my new repository.

After an evening of furious experimentation, I had a complete database to web page end to end implementation of my User entity. I was stoked, still am. I am currently working on getting unit tests in place using Rhino.Mocks, integration tests on my data access layer and fully implementing CRUD in the MVC site. It is a hell of a lot of fun.

If anyone is interested in seeing what I am working on or want a simple example of using all these things together in an easily understandable way, I posted my work to CodePlex. If you are new to this stuff like I am, download it and check it out. If you are an old hat and want to give me some pointers or tips, please download it and fill me in.

If you work with me and happen to read my blog and are interested, I would love to talk to you about the project and what I learned and discovered. Hit me up.


 
Categories: Development | Fundamentals | Tools | Unit Testing

I came across an interesting issue tonight exploring the use of Rhino.Mocks in unit tests. I have a class UserRepository that implements my current understanding of the Repository Pattern. My repository uses the interface IDataProvider to persist my User entity. The concrete class UserDataProvider wraps NHibernate.

My goal was to write unit tests that cover the methods of UserRepository. I used Rhino.Mocks to mock away UserDataProvider to prevent actually needing a database.

Things were going fine:

public void SaveTest(){
            MockRepository mock = new MockRepository();

            IDataProvider dataProvider = 
                  (IDataProvider) mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);
            User u = new User();
            
            Expect.Call(dataProvider.Save(u)).Return(1);
            Expect.Call(dataProvider.GetById(1)).Return(u);
            
            mock.ReplayAll();
            User x = target.Save(u);
            mock.VerifyAll();

            Assert.AreEqual(x, u);
        }
 
public void GetListTest(){
            MockRepository mock = new MockRepository();
            IDataProvider dataProvider = 
                 (IDataProvider)mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            Expect.Call(dataProvider.GetList()).Return(
                new List<object> { new User(), new User()});

            mock.ReplayAll();
            IList<User> users = target.GetList();
            mock.VerifyAll();
            Assert.AreEqual(2, users.Count);  
        }

Then I hit a snag. My User entity has a property Id that is read only. The users Id comes form the database and should not be able to be modified. So my next test has a bit of a problem and fails to compile.

public void GetByIdTest() {
            MockRepository mock = new MockRepository();

            IDataProvider dataProvider = (IDataProvider)mock.CreateMock<IDataProvider>();
            UserRepository target = new UserRepository(dataProvider);

            //TODO: Interesting Problem here. My actual dataProvider uses NHib
            //and would be able to meet this expectation. But my mock
            //cannot set the read only id property so this test will not
            //even compile.
            Expect.Call(dataProvider.GetById(1)).Return(new User() { Id = 1 });

            mock.ReplayAll();
            User u = target.GetById(1);
            mock.VerifyAll();

            Assert.AreEqual(1, u.Id);
        }

 

NHibernate has no problem injecting the value when I fetch the object from it, but my simple little expectation above chokes on it. I am not sure how to get around this one with out violating the intent of the test. I'll have to dig into the Rhino.Mocks documentation and see what tools it offers to get around this situation.

So far Rhino.Mocks is a great time saver. If I actually had to generate a fake for IDataProvider it would take quite a bit of time. I'll have to work it into my regular work life and see how it fairs there.

I'll update this post when I find a resolution to the issue at hand.


 
Categories: Development | Tools | Unit Testing