Archive

Author Archive

Testing Windsor component registrations

July 16, 2009 Leave a comment

Having previously used Windsor on other projects and experienced the pain of debugging incomplete or invalid component registration via YSOD, I decided to be a little more proactive in my approach to container configuration on my current project.  This time round I have a suite of tests that (hopefully) cover all of the components that should be registered, and already these tests have exposed one problem that has arisen due to my ignorance around the NHibernate Facility.

In general, testing component registrations is as simple as resolving all of the types for a given service and ensuring the count matches some value you have determined via other means, like so:

        [Then]
        public void all_of_the_controllers_in_the_assembly_should_be_registered()
        {
            var controllerAssembly = typeof( RegistrationController ).Assembly;
            var controllerCount =
                controllerAssembly.GetExportedTypes()
                    .Where( t => t.IsSubclassOf( typeof( Controller ) ) && !t.IsAbstract )
                    .Count();
            var registeredControllerCount = _container.ResolveAll<Controller>().Length;
            registeredControllerCount.ShouldEqual( controllerCount );
        }

(_container is an IWindsorContainer instance and the [Then] attribute is from my customised xUnit BDD implementation)

The problem occurs when you try to use the same approach with open generic types such as IValidator<> – ResolveAll returns and array and you can’t create an array of open generic types. To get around this you need to retrieve the collection of handlers for the components rather than the components themselves (this is based on the assumption that a handler is generated for every registration – which I cannot disprove so I will go with it for now).

Using this approach, I can ensure the registration of all my IValidator<> instances with the following:

        [Then]
        public void all_of_the_validators_in_the_assembly_should_be_registered()
        {
            var validatorAssembly = typeof( RegistrationCommandValidator ).Assembly;
            var validatorCount =
                validatorAssembly.GetExportedTypes()
                    .Where( t => t.IsSubclassOf( typeof( IValidator<> ) ) && !t.IsAbstract && !t.IsInterface )
                    .Count();
            // Can't use ResolveAll as there is no way to create an array of an open type
            var registeredValidatorCount = _container.Kernel.GetHandlers( typeof( IValidator<> ) ).Length;
            registeredValidatorCount.ShouldEqual( validatorCount );
        }

The only difference to the first test is the call to _container.Kernel.GetHandlers( ... ) instead of _container.ResolveAll<...>().

xUnit, RunWith and ReSharper

July 6, 2009 Leave a comment

It works!  I’ve still got a lot of work to do to clean things up and look at getting it patched into the codeplex source, but this screenshot below shows the ReSharper test runner executing tests using a custom ITestClassCommand.  If you need it right now, post a comment below otherwise I will try and get something sorted in the next couple of weeks.

xUnit + RunWith + R#

Categories: General

Yet another BDD extension for xUnit

June 22, 2009 Leave a comment

I’ve been “test infected” for a while and while I still lack the hardcore discipline to apply TDD to everything I do, I have managed to use it through a couple of projects I have worked on.  One of the things I noticed as I was writing more and more tests is that I went from testing a scenario per method (with lots of test methods per class) to testing a scenario per class.  Looking around the web, I think a lot of people go through this evolution toward BDD style testing where you set up a context, apply some action to it and then veryify the results are what you expected.

For my next project, I wanted to formalise this style of testing and make it as easy as possible to do, to that end I did a bunch of research, selected xUnit as my testing framework and then stole incorporated ideas from all over the place to come up with something that allowed me to write tests in the following style:

    public class When_popping_an_empty_operand_stack
    {
        private OperandStack _operandStack;
        private long _value;

        public Action Given()
        {
            return () => { _operandStack = new OperandStack(); };
        }

        public Action When()
        {
            return () => _value = _operandStack.Pop();
        }

        [Then]
        public void the_value_should_be_zero()
        {
            Assert.Equal( 0L, _value );
        }
    }

Note: This is where I ended up after numerous revisions determining what I could and could not do while trying to keep the noise and ceremony to a minimum.

This approach treats the test class as the context (or world) that you set up using the Given delegate, alter using the When delegate and verify the outcomes in the methods marked with the [Then] attribute.  If you’ve seen MSpec then you are probably thinking “Hey, thats just like MSpec… but not quite” and you’d be dead right.  Of all the approaches and syntaxes I saw, MSpec had the best and it was the one that came the closest to doing what I wanted, apart from one (not so minor) issue – the R# test runner does not play nice with MSpec.

To achieve the above test using xUnit was relatively simple and borrowed heavily from this posting by Frederik Kalseth.  The reason I didn’t simply use his version was the requirement to inherit from a common base class.

A final hat tip must be given to Phil Haack as it was his post on Streamlined BDD Using SubSpec for xUnit.NET that set me down the path of playing with xUnit to make it test the way I wanted to.

Going forward, I’ve been looking at xUnits IUseFixture interface and wondering about using Fixtures as a means for encapsulating context where you want to share it across multiple test classes… but I’ll solve that when I get around to needing it.  Code for making xUnit behave as shown in the code above is below. Feedback on both the test approach (Given / When / Then) and the implementation of the xUnit extensions is most welcome.

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    public class ThenAttribute : FactAttribute
    {
        protected override IEnumerable<ITestCommand> EnumerateTestCommands(MethodInfo method)
        {
            foreach( var testCommand in base.EnumerateTestCommands( method ) )
            {
                yield return new ThenCommand( testCommand );
            }
        }
    }

    public class ThenCommand : ITestCommand
    {
        private readonly ITestCommand _innerCommand;

        public ThenCommand( ITestCommand innerCommand )
        {
            _innerCommand = innerCommand;
        }

        public MethodResult Execute( object testClass )
        {
            var given = GetGivenAction( testClass );
            EnsureGivenIsValid( given );
            var when = GetWhenAction( testClass );
            EnsureWhenIsValid( when );
            given();
            when();
            return _innerCommand.Execute( testClass );
        }

        public XmlNode ToStartXml()
        {
            return _innerCommand.ToStartXml();
        }

        public string DisplayName
        {
            get { return _innerCommand.DisplayName; }
        }

        public bool ShouldCreateInstance
        {
            get { return _innerCommand.ShouldCreateInstance; }
        }

        private Action GetGivenAction( object testClass )
        {
            return GetAction( testClass, "Given" );
        }

        private void EnsureGivenIsValid( Action given )
        {
            if (given == null)
            {
                throw new ArgumentException( "Test class does not contain a Given() method "
                + "or the Given() method does not return an Action delegate.  "
                + "Please ensure the test class implements a public method with the following signature: "
                + "Action Given()");
            }
        }

        private Action GetWhenAction( object testClass )
        {
            return GetAction( testClass, "When" );
        }

        private void EnsureWhenIsValid(Action when)
        {
            if (when == null)
            {
                throw new ArgumentException("Test class does not contain a When() method "
                + "or the When() method does not return an Action delegate.  "
                + "Please ensure the test class implements a public method with the following signature: "
                + "Action When()");
            }
        }

        private Action GetAction(object testClass, string methodName)
        {
            var wrappedTestClass = Reflector.Wrap(testClass.GetType());
            var givenMethod = wrappedTestClass.GetMethod( methodName );
            if (givenMethod == null)
            {
                return null;
            }
            if(givenMethod.ReturnType != typeof(Action).FullName)
            {
                return null;
            }

            return (Action)givenMethod.MethodInfo.Invoke( testClass, null );
        }
    }

Categories: c#, TDD, Unit Testing

Recreating an SVK Depot

May 14, 2009 Leave a comment

I’ve been playing around with svk on my laptop – it allows me to work disconnected from the svn repository at work (which makes it easier to work from home :) ).

Recently, after doing a big chunk of work, I was syncing and merging and noticed some weird issues – so I thought I’d just delete the depot and recreate it then mirror the repository again.  After detaching the depot and deleting the contents of the folder, I tried adding a new depot using svn depotmap and svn depotmap –init but I couldn’t mirror the svn repository again as I was getting a file not found error.  After much uninstall / reinstall thrashing and general frustration I deleted the directory I specified in the depotmap and retried svk depotmap –init and it worked!

Turns out that if the directory specified in the depotmap exists (even if it is empty), the depot will not be initialised.  The key to recreating a depot is to delete the folder specified in the depotmap – not just the contents of the folder.

Categories: Source Control

Poka-Yoke vs Baka-Yoke…

April 28, 2009 Leave a comment

… or mistake proofing vs fool proofing.

Ayende recently caused something of an uproar on his discussion of repositories and query objects (see the post here and follow ups here and here).

The interesting thing about the responses is not that they argued against the underlying  architectural principles, but that the arguments seemed to be about protecting developers from doing dumb things.

Why is it that developers want to protect everyone else from the component / service / framework that they have just written / integrated?  Are we that afraid of the software we write that we must protect everyone else from it no matter the cost?  It was while reading another blog post that I stumbled across the perfect phrase for this approach – Baka-Yoke or “fool-proofing”.  

The problem with Baka-Yoke is that when you fool-proof something, the universe tends to create a better class of fool.  The other problem with Baka-Yoke is the cost.   The cost of using Baka-Yoke is a nasty multi-pronged beast:

  • You have to write more code to protect that code you just wrote and now need to be “protected”
  • Because you are restricting the use of that awesomely great gee-whiz powerful component you just wrote or  integrated, you loose some of the power of that component.
  • You’ve lost flexibility and the ability to adapt to new situations – no longer can you weild the full power of the code you just “protected”, and to respond to new situations you have to write yet another adapter or bridge or some other form of abstraction to provide access to the functionality you now need.
  • Perhaps the greatest loss of all; those “stupid” developers you are protecting – they will never learn about the underlying component or code you are “protecting”.  This means they will never be able to make intelligent decisions about it’s use or use it in new and previously unforseen ways to achieve great things (okay so slight exaggeration but you get my drift).

Instead of excercising Baka-Yoke, maybe you should consider Poke-Yoke?

Poka Yoke is the practice of “mistake-proofing” work. It’s another principle from the Toyota Production System. Poka-Yoke mechanisms ensure that the user or operator can’t make a mistake. For example a plug that can only be inserted correctly (like the 3 pin UK plug) or can be inserted in two ways that are both correct (like a 2 pin plug).

Poka Yoke is not Baka-Yoke or “fool-proofing”. The goal is not to prevent idiots from doing the wrong thing, but to make intelligent people do the right thing.

From Thinking for a Change - Beyond Jidoka – Poka-Yoke

We can practise Poke-Yoke without too much extra effort in software development.  The quickest and easiest mechism we have to mistake-proof our work is testing – automated, repeatable tests that can be run to verify that the method / component / application is operating as expected.  

I think the Baka-Yoke mentality is a holdover from times before unit-testing become as openly accepted as it is today (at least in the .NET world).  I think the fastest way past this mindset is the complete and utter acceptance of testing as an integral part of any development work – in essence the application of Poke-Yoke.

Categories: General

NHibernate Lambda Extentions Gotcha

March 4, 2009 Leave a comment

Recently I came across the open source NHibernate Lambda Extensions project on Google Code.  This small library provides a set of extension to remove the magic strings from your NHibernate criteria queries, and it’s great (once you get used to the conventions).

I’ve been slowly migrating queries across to use NHLambda and tripped up on the following query which is effectively Survey.Status == Complete and Survey.Questionnaire.Id = questionnaireId.


            var expected = DetachedCriteria.For<Survey>()
                .Add( Restrictions.Eq( "Status", SurveyStatus.Complete ) )
                .Add( Restrictions.Eq( "Questionnaire.Id", questionnaireId ) )
                .CreateAlias( "Answers", "answerAlias" )
                .SetProjection( Projections.Property( "answerAlias.Id" ) );

Initially I had converted it as


            Answer answerAlias = null;
            var actual = DetachedCriteria.For<Survey>()
                .Add<Survey>( s => s.Status == SurveyStatus.Complete )
                .Add<Questionnaire>( q => q.Id == questionnaireId )
                .CreateAlias<Survey>( s => s.Answers, () => answerAlias )
                .SetProjection( LambdaProjection.Property( () => answerAlias.Id ) );

which actually generates a query equivalent to Survey.Status == Complete and Survey.Id == questionnaireId.

After kicking myself for being lazy and not writing a test first, I wrote a test and realised that I had implicitly traversed an association in the second restriction.  There are two ways to solve this, either explicitly create the alias, or (as I have just considered and tested while writing this post) correctly place the restriction on the survey and navigate to Questionnaire.Id.  Both approaches are shown below.


            // Explicitly create and navigate the alias
            Questionnaire questionnaireAlias = null;
            Answer answerAlias = null;
            var actual = DetachedCriteria.For<Survey>()
                .Add<Survey>( s => s.Status == SurveyStatus.Complete )
                .CreateAlias<Survey>( s => s.Questionnaire, () => questionnaireAlias )
                .Add( () => questionnaireAlias.Id == questionnaireId )
                .CreateAlias<Survey>( s => s.Answers, () => answerAlias )
                .SetProjection( LambdaProjection.Property( () => answerAlias.Id ) );

            // Apply the restriction to Survey and navigate to Questionnaire.Id
            var actual2 = DetachedCriteria.For<Survey>()
                .Add<Survey>(s => s.Status == SurveyStatus.Complete)
                .Add<Survey>(s => s.Questionnaire.Id == questionnaireId)
                .CreateAlias<Survey>(s => s.Answers, () => answerAlias)
                .SetProjection(LambdaProjection.Property(() => answerAlias.Id));

I don’t know which one of these is more correct (or even if one is better that the other), but they both look a hell of a lot better than the original with it’s many magic strings.

Anyway, the moral of this story is twofold; one, beware implicit association traversals when migrating queries to NHLambda and two, don’t be a clown – write unit tests to cover the migrated queries!  =)

Dear advertisers

February 26, 2009 1 comment

if you want me to see your advertisements, stop making them in your face, attention grabbing distractions.

Nearly every day I visit a NZ news site called Stuff, it’s a good way to get a quick snapshot of the days headlines and give my brains some downtime from coding.  I used to use IE, it was there and I didn’t have to think about it, but then a couple of years ago Stuff started adding those annoying fly out ads that forced me to interact with them.  I resented having such an intrusive ad so I went looking and found Firefox and Adblock, I haven’t looked back… until recently.

With the advent of Google Chrome I found a nice clean browser that does what I need and does it pretty well, except it doesn’t block ads.  I went back to the Stuff site today – this time I was using Chrome, and I was assaulted by annoying in your face adds that distracted me from my true purpose once again.  I wouldn’t mind the ads, except the incessant moving / blinking / changing keeps dragging my focus away from what I was reading ( most ads seem to act like that fluorescent light fitting in your office with the broken starter ).

I’m now back using Firefox to peruse the Stuff site and none of their advertisers get me eyeballing their ads, the only downside for me is I don’t get to choose the browser I use.

End rant.

PS If you’re still using IE in any shape or form – go grab Firefox (and maybe even Chrome).  Microsoft dropped the ball with IE long ago and still haven’t figured how to pick it up again.

Categories: General

SubmittedWith Parameter Binder – Which button was clicked?

February 23, 2009 2 comments

What do you do when you want to have more than one button submit a form and vary the actions taken depending on the button press?

Previously I would have done something like:


bool resetFilter = QueryContainsKey( "ShowAll" );

where QueryContainsKey is a simple method that scans the query collection looking for the “ShowAll” key (when an html form is submitted, the name of the button is passed in the request, in the same way that other form elements are – just without a value).

This approach works reasonably well – except it’s kind of ugly, repetative (I need to apply the same logic in at least 3 controller methods) and makes testing painful as I have to remember to add a value to the Query collection.

Then I discovered the IParameterBinder interface (have a look at the DataBindAttribute code and Ken Egozi’s excellent tutorial) and built the following:

    [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
    public class SubmittedWithAttribute : Attribute, IParameterBinder
    {
        private readonly string _buttonName;

        public SubmittedWithAttribute(string buttonName)
        {
            _buttonName = buttonName;
        }

        public int CalculateParamPoints(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
        {
            if( parameterInfo.ParameterType.Equals( typeof(bool) ))
            {
                return 10;
            }

            return 0;
        }

        public object Bind(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
        {
            var collectionKeys = new List();

            if( context.Request.HttpMethod == "GET" )
            {
                collectionKeys.AddRange( context.Request.QueryString.AllKeys );
            }

            if( context.Request.HttpMethod == "POST" )
            {
                collectionKeys.AddRange(context.Request.Form.AllKeys);
            }

            // Keys must be compared using case insensitive comparer - html is not case sensitive and neither should this be
            collectionKeys.Sort(StringComparer.InvariantCultureIgnoreCase);
            return collectionKeys.BinarySearch( _buttonName, StringComparer.InvariantCultureIgnoreCase ) >= 0;
        }
    }
[/sourceode]

This allows you to define a controller method like:

[sourcecode language='csharp']
public void ViewResults(Guid questionnaireId, [DataBind("SurveyFilter")]SurveyFilterBuilder surveyFilterBuilder, [SubmittedWith( "ShowAll" )]bool resetFilter)
{
...
}

and test it just like any other method, but when the action is called from a form submit, resetFilter will indicate if the form was submitted using the ShowAll button.  The html form looks like:

$Form.FormTag("%{method='Get'}")
<fieldset>
...
<button type="submit" id="apply" title="Apply the filter to the report">Apply</button>
<button type="submit" id="showall" name="ShowAll" title="Show all results">Show all</button>
</fieldset>
$Form.EndFormTag()

Wicked!  Now I have collapsed a bunch of repeated logic into a simple attribute (that is tested) that has the added benefits of making my action method signatures more obvious and made my tests much cleaner.

Updated 24 Feb: Searching the key collection for the button name is now case-insensitive

Categories: MonoRail

Random Thought Experiment – Swapping Variables

February 3, 2009 1 comment

Recently I was reading a post about using a fizzbuzz test to find developers that grok coding.  Some of the comments also talked about using a simple swap test (i.e. swap the values of these two variables) and how this could be done without resorting to the use of a third variable.

While I can appreciate the”geek factor” or XORing variables together such that you can swap their values without requiring the use of a third, I would not want to use this approach anywhere except where memory was extremely limted, it is horribly unclear what is happening to someone that does not know about or understand the approach.  This set me to thinking, how could you swap to variables around in a reasonably clear manner without resorting to the use of a third.  The following is what I came up with.

using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;

namespace Swap
{
    public class Swap
    {
        public static void DoSwap(int a, int b, out int swappedA, out int swappedB)
        {
            swappedA = b;
            swappedB = a;
        }
    }

    [TestFixture]
    public class SwapTest
    {
        [Test]
        public void DoSwap_Should_Swap_A_And_B()
        {
            int a = 3;
            int b = 5;
            Swap.DoSwap( a, b, out a, out b );

            Assert.That( a, Is.EqualTo( 5 ) );
            Assert.That( b, Is.EqualTo( 3 ) );
        }
    }
}

Simple, effective, completely pointless and fun to solve.

Categories: c#, General

NHibernate many-to-many mappings and order-by

February 3, 2009 2 comments

Update: Frederico Tolomei has pointed out that this now works as you would expect if you place the order by on the many-to-many tag like this:

    <bag name="SelectedOptions" cascade="none" lazy="false">
      <key column="Answer" />
      <many-to-many column="AnswerOption" class="AnswerOption"  order-by="DisplayIndex asc"/>
    </bag>

Just found this and it took me a while to figure out so posting here to remind myself as well as help anyone else who stumbles over the issue.

When you configure collection mappings in NHibernate, you can add an order-by attribute and specify the field to order the collection by as well as whether to sort ascending or descending.

With one-to-many mappings, the field you specify is a member of the entity contained in the collection so the following would contain a collection of Question instances sorted by DisplayIndex.

<bag name="Questions" cascade="all" order-by="DisplayIndex asc" lazy="false" fetch ="subselect">
   <key column="QuestionnaireSection" />
      <one-to-many class="Question" />
    </bag>

However, if the mapping is a many-to-many, the order by clause is applied to the association table – the table in the middle of a many-to-many association mapped into a relational database. I cannot use the order-by attribute on the following collection mapping.

    <bag name="SelectedOptions" cascade="none" lazy="false">
      <key column="Answer" />
      <many-to-many column="AnswerOption" class="AnswerOption" />
    </bag>

The implementation of this may be erroneous (and could be argued as counter-intuitive), however as it stands the order-by clause of a collection mapped as a many-to-many is not overly useful as we cannot sort a collection of entities in the same manner as we can with a many-to-one mapping.

Categories: NHibernate
Follow

Get every new post delivered to your Inbox.