Tuesday, October 20, 2009

What is the true value of experience?

I recently had an encounter with a fellow software developer that quickly escalated into a philosophical discussion where neither of us was right or wrong yet I could sense both of us digging our heels in preparing to obliterate the other with our hulk-like rage.  From his perspective, I was questioning, second-guessing and disagreeing with his philosophy - which coincidentally has been adopted as the company's philosophy since his assention into the "architect" position.  For me, I felt like my perspective was being dismissed out-of-hand.  Hell, I'd never even been asked before the company adopted these (flawed, imo) philosophies despite having spent years honing my beliefs while holding that same position in other companies.

That same night I had a long drive during which to assess if my feelings were simple jealousy over not getting the position or rooted elsewhere.  After a quick debate, I came to the conclusion that I most certainly did resent not having the position and having philosophies so contrary to my own dictated to me.  My thoughts wandered until they finally settled on one question:

How could I not be the better choice for the position?

Let's say you are hiring a new developer for your team.  One candidate is right out of college with a Computer Engineering degree, has had all of the standard courses and kicks butt in Halo.  The other has been a professional developer for 20+ years working for a few large names in your industry but has very little practical experience with the tools and languages you are using.  Do you dismiss the second for lack of experience with the toolset?  Or maybe you eliminate the first because he doesn't have any real-world experience?

What if you add a third candidate?  This one also has 20+ years of experience but has bounced around a bit with some years developing manufacturing applications, some with ISVs, others as a consultant working on anything the customer will pay for and some doing government contract work.  Any preferences now?

I challenge you that any real assessment is not possible without some additional context.  For instance, are we hiring a UI developer or an Architect?  Candidates 2 and 3 would (should) never consider a junior position and would be disgruntled quickly if they did.  This wouldn't be good for the cohesiveness and morale of the team and you'd most likely be looking to fill the same position again relatively soon.  The first candidate, on the other hand, could no more direct the efforts of your development team than my dog.

So, if we were looking for an Architect, Manager or Senior Developer, how do we distinguish the last two candidates?

By understanding the true value of experience.

Simply putting in the years isn't enough.  It's what you do with that time and what you are exposed to that counts.

The second candidate in our little example has put in the time but spent that time working for a handful of companies thereby limiting his exposure to what those companies allowed him to see and do.  Their tools, their techniques, their processes, etc.  He may be very good at those things, but his experiences have been limited and, as a result, so is his vision.

When first glancing at the third candidate's resume, you might wonder why he/she didn't stay in one place for very long and lean towards the second candidate because they demonstrated longevity.  I will offer to you that longevity can be perceived both ways as well.  Instead of representing dedication and loyalty, perhaps it shows that the developer didn't have the confidence or courage to test the market.  Changing jobs is hard, we all know that.  Unless the third candidate was forced to change, maybe we should see this as a positive trait - something that reflects a strong character, someone who welcomes a challenge and doesn't settle for what's convenient or status quo.

Also consider that with such a background comes diversity and exposure to many different approaches, etc. - all of the things that were limited with candidate 2.  Because the last candidate has worked in different industries, he/she has been exposed to different pespectives.  Working as a consultant means that he/she has worked closely with customers which, as well all know, means they've dealt with change.  And, if the customer-base was industry-agnostic, their exposure is even greater.

So, what is the true value of experience?  Great.  But you have to actually accumulate true experience to achieve this value.  As I said earlier, simply putting in the time doesn't get you there.

Btw, can you guess which candidate I am in my little story? ;-)

Tuesday, October 6, 2009

Using Moq with Spring.NET

Not long into my evaluation of Moq as a mocking framework for our unit testing needs, I had to test a class that used the Spring.NET framework to instantiate a dependant object. Per the rigid definition of a unit test, I wanted to eliminate Spring.NET from the equation. My unit test shouldn't fail because I didn't configure Spring.NET correctly. Besides that, I needed to test the class under different circumstances and couldn't do that without making changes to the configuration file - another TDD no-no.

This part was easy enough by refactoring the method that uses Spring.NET so that I could override it in my test code. I believe I saw this technique referred to as "Inherit and Override". To do this, I simply subclassed the class under test to create a "testable" version with an override for the method that called Spring.NET for the dependant object. In my "testable" class, I return a mock object instead. Nice and simple!

Where things became a bit more complicated is when I wanted to put together a system test for the same functionality. In this case, I do want to use Spring.NET to instantiate the dependant object but still want to mock the object used for testing purposes. Short version is that it handles file I/O which I never want to execute in my tests.

Fortunately, the Moq framework comes with a MockFactory class that can be used in the Spring.NET configuration file to create the mock object we desire for the test. Here is how I setup the configuration file for my test assembly:

<objects xmlns="http://www.springframework.net">
    <object name="MockFactory" type="Moq.MockFactory, Moq">
        <constructor-arg type="Moq.MockBehavior" value="Default" />

    <object name="MyObject"
               factory-method="Create<IMyObject>" />

Now, when running my test, the class calls into the Spring.NET framework for the object which uses the configuration file to call the Create method on the MockFactory class, returning a mock object instead of the concrete class in our application.

There is one catch, however. The object returned from the MockFactory.Create method is of the type Mock<T>. Unless you code your class to accept this type, which would be poor practice, you'll get an InvalidCastException. To work around this, I created my own MockFactory class that delegates to the Moq class but unwraps the returned object so that mocked instance is returned as follows:

internal class MockFactory
    private static Moq.MockFactory _moqFactory;

    static MockFactory()
        _moqFactory = new Moq.MockFactory(Moq.MockBehavior.Default);

    public T Create()
        where T : class
        return _moqFactory.Create().Object;

I then changed the configuration file to use this class.

<objects xmlns="http://www.springframework.net">
    <object name="MockFactory"
               type="Testing.MockFactory, Testing" />

    <object name="MyObject"

In the end, getting Moq to play will Spring.NET turned out to be relatively easy. Sure, I had some setup work to do, but now that I've done it once...