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

Karl Seguin of CodeBetter.com released a 79 page ebook called Foundations of Programming yesterday. Browsing the table of contents, I found a ton of good information is covered here. Some highlights include: YAGNI & DRY principals, Explicitness, Cohesion & Coupling, Domain Driven Design... The list just goes on and on and on.

If you want to read about the stuff that a giant Wrox tomb will never mention, grab this ebook as a great launching point.


 
Categories: Development | Events | Fundamentals

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

Over the course of the last couple months I have been working diligently to migrate the application I inherited from the wild wild west of unmanaged corner cutting contractor land to the happy kingdom of semi-intelligent source control.

I have successfully migrated what we have come to know as "what we think production is built with" source in to Team Foundation Server source control, cleaning up along the way. Why exactly this particular batch of contractors felt it was necessary to include references to both the 2.0 and 3.0 Enterprise Application Blocks, I may never know. I suspect they felt it was 2x more "Enterprise-y".

Next up on my path to Agile Nirvana, I whipped up a set of build scripts that produce a consistent build every time. Imagine that! My server support people are so happy with me.

The system I am working on is somewhat interesting. The application went live last summer and was officially handed over to a group of maintenance developers. A new project was immediately started to add new functionality while the maintenance guys fixed up bugs. I currently work with the New Development group.

The maintenance guys decided they wanted in on all this awesome TFS goodness. So I spun them off a branch and let them go on their merry way. That was until they decided they were ready to start rolling forward into production.

That is when I realized that all of my build scripts no longer worked. I would fire up a build using Team Builds in Team Explorer, it would do it's thing pulling down source code and firing off MSBuild to compile and then throw errors.

I checked on the build server in the location where source is downloaded and Team Build was no longer pulling down the source for my Main branch. The only thing be retrieved from Source Control was my Branches directory. Obviously the dirty maintenance branch hosed by lovely build process.

I checked my build definitions and mapping files. My source tree looks something like this:

$/PROJECT
..Branches
    ..2.0.1.0-APPLICATION-branch
..Main
   ..Framework
   ..APPLICATION
   ..Samples
   ..Utilites
..TeamBuildTypes
The 2.0.1.0 node is a branch of $/PROJECT/Main/APPLICATION. My workspace mapping pretty much looks like so:

<InternalMapping ServerItem="$/APPLICATION" LocalItem="flibbityjibits" Type="Map" />

I have a few cloaked paths as well all related to $/PROJECT/Main/Something. When I execute my Team Builds Branches and TeamBuildTypes are retrieved from source control and Main is ignored.

My buildlog shows that CoreGet is retrieving the latest:

Get Version="T" Recursive=True Force=True Workspace="NinjaWarrior"

There was something I was missing here. I shot off an email to the Seattle ALT.NET mailing list, more in a effort to articulate the issue well than expecting them to solve my issues or anything. Kinda just getting it all out as I understand the issue for the eventual call to tech support.

I went home that night utterly devastated that my painstakingly lovingly crafted system had failed so spectacularly.

At home I was playing some Lego Indy with the wife on the Xbox and letting the subconscious work on it. And finally the light bulb went off.

I have other branches in the Branches folder that caused no problem when they were created. I thought to myself, "Self, it's not the branch that did it.. It must be something that you did at the same time you created the branch."

My assumption about the branch breaking my build came directly from my Jump To Conclusions Mat.
I created this branch for an external group who is adding functionality. In an effort to keep my main pristine, I locked it down so that only members of the group "Tech Leads" could check in to Main.

This had to be the cause.. when I realized it last night I almost went back in to work... but come on its Lego Indy!

So I get to work this morning and checked the membership of "Tech Members" and surprise, surprise... TFSService is a member... The build service uses this account to access TFS...

So I quickly added it to the leads group and verified that my builds worked again and went to repair the dent I put in the wall from beating my head against it.

So Lessons Learned here:
1. Respect the build user, he can make you a very sad panda.
2. I've automated the build, its time to get a nightly build going so these changes are fresh in my mind when stuff breaks.
3. While I am at it might as well look into setting up CI to the Dev environment with the nightly.
4. Indy really can accomplish anything.

So in the end, I created my own problem. Thanks to all the ALT.NET mailing list readers for silently laughing at me while I verbalized (textualized?) the issue on the mailing list and worked through it.

I'll be here all week.


 
Categories: Development | MSBuild | Random

Please join us on Thursday, June 12th for a presentation on Silverlight 2.0 by Erik Mork.

Meeting Specifics:

Erik Mork will be returning to Olympia in June to present Silverlight 2.0 to the South Sound .NET User Group. Our last visit from Erik was in July 2007, when he told us about Silverlight 1.0 and looked forward to what might be in version 2.0. Now, with Silverlight 2.0 released in Beta, he can come back and give us the next chapter in this ongoing story.

Erik was with Tranxition last year and looking toward self-employment. He's made that leap now, founding Silver Bay Labs. In addition, he and with his wife is producing a Silverlight podcast called Sparkling Client. Recent shows featured interviews with Adam Kinney aka The Silverlight Surfer and Jesse Liberty aka Captain Silverlight.

If you're into Silverlight, definitely check out what the Morks are up to and plan to attend the South Sound .NET meeting on June 12th with Erik and Silverlight 2.0.

 

Meeting Specifics:
June 12th, 7 - 9 pm
Olympia Center (222 Columbia NW)
All attendees are eligible for the prize drawings. Past prizes have included t-shirts, technical books, passes to Devscovery, copies of Visual Studio, Vista, Office 2007 and more.

Don't forget to let your friends and co-workers know about this meeting.  Feel free to forward this email and/or direct them to www.ssdotnet.org for more information.


 
Categories: Development | Events | Local