Archive

Archive for the ‘Unit Testing’ Category

Using Machine.Specifications with nant

October 20, 2009 1 comment

Wasted at least an hour today trying to track down an issue running my specs with NAnt. Turns out the problem was using <arg value=”{assembly1} {assembly 2}”  instead of <arg line=”{assembly1} {assembly2}” />.

The subtle difference between value and line is that value allows spaces and presents this to the exe as one argument by quoting the content of the attribute, whereas line passes the content of the attribute as it appears ( so the console runner sees 1 arg in the form “{assembly1} {assembly2}” instead of 2 separate args).  This problem presents itself as an error containing the following text :

Missing Assembly: {assembly1} {assembly2}

The xml for running machine.specifications with NAnt is:

    <target name="test.mspec" unless="${test.skip}">
        <mkdir dir="${test.specreportdir}" />
        <exec program="${test.mspecrunner}"
            basedir="${test.mspecdir}"
            workingdir="${root.dir}">
            <arg value="--silent" if="${teamcity.build}" />
            <arg value="--teamcity" if="${teamcity.build}" />
            <arg value="--html" /><arg dir="${test.specreportdir}" />
            <arg line="${test.assemblies}"/>
        </exec>
    </target>

where:

  • ${test.specreportdir} is the directory for the reports to go into
  • ${test.mspecrunner} is machine.specifications.consolerunner.exe
  • ${test.mspecdir} is the directory containing the mspec console runner
  • ${root.dir} is the root project directory
  • ${teamcity.build} is set from a team city specific build that is used for TC builds
  • ${test.assemblies} is a list of the assemblies containing specs separated by spaces

Simplify IUserType Testing

October 16, 2009 4 comments

Background

The application I am currently working on makes ( will make ) heavy use of the .NET TimeZoneInfo class to allow us to display times in the current users local time. To achieve this we need to capture and store the timezone from the user.

Capturing the timezone is relatively simple, I use a slightly modified version of this technique used by Nate Kohari’s most excellent Zen.

Storing the timezone provides an interesting choice of options;

I could store the raw offset in hours ( a double ) or in minutes ( an int ) and recreate the TimeZoneInfo each time I want to display a date or time in the users local time. This has the benefit of being incredibly simple and, with a little work to create an extension method, generates almost no duplication except the act of converting the double or int into a TimeZoneInfo.

The second alternative was to let my trusty ORM do the work for me. I use NHibernate and after a little research I found the following articles about creating an IUserType that would allow me to map a TimeZoneInfo into a database field. If you want all the gory details of how to do it go and read those articles, otherwise the code for my TimeZoneInfoUserType is shown at the bottom of the post ( see the section titled The Implementation ).

The Useful Stuff

Normally I use a BDD style approach for building something like this, but as I wasn’t sure how to solve the problem, I spiked out the approach, then added the tests and refined the implementation as required.

Part of spiking out the solution was figuring out how to test it and this initially tripped me up as I was considering mocking IDbCommand and IDataReader ( which gets ugly fast ).

After a little bit of thought, I figured I could use a SqlCommand for the IDbCommand. The following snippet shows what you need to do to use a SqlCommand for testing your NullSafeSet ( note where parameter index comes from ).

_command = new SqlCommand();
_parameterIndex = _command.Parameters.Add( _command.CreateParameter() );

// ... this is then used in the NullSafeSet test ...
_userType.NullSafeSet( _command, null, _parameterIndex );

To find an acceptable IDataReader stand-in, I went poking around with Reflector and found an IDataReader implementation that wraps a DataTable. This gave me a means of quickly and easily controlling the data being passed to the code under test. The following snippet shows how you can set up an IDataReader from a DataTable in as little as 5 lines of code for testing your NullSafeGet ( note the data reader must be “initialised” by calling Read() before using it ):

var dataTable = new DataTable();
dataTable.Columns.Add( ColumnName, typeof( int ) );
dataTable.LoadDataRow( new object[] {TimezoneOffset * 60}, true );
_dataReader = new DataTableReader( dataTable );
_dataReader.Read();

// ... this is then used in the NullSafeSet test ...
_timezoneInfo = (TimeZoneInfo) _userType.NullSafeGet( _dataReader, new[] {ColumnName}, null );

The full source for the TimeZoneInfoUserType and the associated tests is shown below:

The Implementation

    public class TimezoneInfoUserType : IUserType
    {
        public new bool Equals(object x, object y)
        {
            if( ReferenceEquals( x, y ) )
            {
                return true;
            }
            if( x == null || y == null )
            {
                return false;
            }

            return x.Equals( y );
        }

        public int GetHashCode( object x )
        {
            return x.GetHashCode();
        }

        public object NullSafeGet( IDataReader rs, string[] names, object owner )
        {
            var rawValue = NHibernateUtil.Int32.NullSafeGet( rs, names[ 0 ] );
            if( rawValue == null )
            {
                return null;
            }
            var timezoneOffsetMinutes = (int) rawValue;
            var timezoneOffset = new TimeSpan( 0, timezoneOffsetMinutes, 0 );
            return TimeZoneInfoFactory.Create( timezoneOffset.TotalHours );
        }

        public void NullSafeSet( IDbCommand cmd, object value, int index )
        {
            if(value == null)
            {
                NHibernateUtil.Int32.NullSafeSet( cmd, null, index );
                return;
            }
            var timezoneInfo = (TimeZoneInfo) value;
            var offsetInMinutes = timezoneInfo.BaseUtcOffset.TotalMinutes;
            NHibernateUtil.Int32.NullSafeSet( cmd, Convert.ToInt32( offsetInMinutes ) , index );
        }

        public object DeepCopy( object value )
        {
            return value;
        }

        public object Replace( object original, object target, object owner )
        {
            return original;
        }

        public object Assemble( object cached, object owner )
        {
            return cached;
        }

        public object Disassemble( object value )
        {
            return value;
        }

        public SqlType[] SqlTypes
        {
            get { return new[] {SqlTypeFactory.Int32}; }
        }

        public Type ReturnedType
        {
            get { return typeof( TimeZoneInfo ); }
        }

        public bool IsMutable
        {
            get { return false; }
        }
    }

The Tests
Note: If you are wondering about the =()=> sequence, I use MSpec for my testing.

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_saving_a_null_TimezoneInfo
    {
        static int _parameterIndex;
        static TimezoneInfoUserType _userType;
        static IDbCommand _command;

        Establish context = () =>
        {
            _userType = new TimezoneInfoUserType();
            _command = new SqlCommand();
            _parameterIndex = _command.Parameters.Add( _command.CreateParameter() );
        };

        Because of = () =>
            _userType.NullSafeSet( _command, null, _parameterIndex );

        It the_offset_is_stored_as_null = () =>
            ((IDataParameter)_command.Parameters[ _parameterIndex ]).Value.ShouldEqual(DBNull.Value);
    }

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_saving_a_TimezoneInfo_with_a_zero_offset
    {
        static int _parameterIndex;
        static TimezoneInfoUserType _userType;
        static IDbCommand _command;
        static TimeZoneInfo _timezoneInfo;

        Establish context = () =>
        {
            _timezoneInfo = TimeZoneInfoFactory.Create( 0 );
            _userType = new TimezoneInfoUserType();
            _command = new SqlCommand();
            _parameterIndex = _command.Parameters.Add( _command.CreateParameter() );
        };

        Because of = () =>
            _userType.NullSafeSet(_command, _timezoneInfo, _parameterIndex);

        It the_offset_is_stored_as_zero = () =>
            ( (IDataParameter) _command.Parameters[ _parameterIndex ] ).Value.ShouldEqual( 0 );
    }

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_saving_a_TimezoneInfo_with_a_positive_offset
    {
        const int TimezoneOffset = 12;
        static int _parameterIndex;
        static TimezoneInfoUserType _userType;
        static IDbCommand _command;
        static TimeZoneInfo _timezoneInfo;

        Establish context = () =>
        {
            _timezoneInfo = TimeZoneInfoFactory.Create( TimezoneOffset );
            _userType = new TimezoneInfoUserType();
            _command = new SqlCommand();
            _parameterIndex = _command.Parameters.Add( _command.CreateParameter() );
        };

        Because of = () =>
            _userType.NullSafeSet( _command, _timezoneInfo, _parameterIndex );

        It the_offset_is_stored_in_minutes = () =>
            ( (IDataParameter) _command.Parameters[ _parameterIndex ] ).Value.ShouldEqual( TimezoneOffset * 60 );
    }

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_saving_a_TimezoneInfo_with_a_negative_offset
    {
        const int TimezoneOffset = -12;
        static int _parameterIndex;
        static TimezoneInfoUserType _userType;
        static IDbCommand _command;
        static TimeZoneInfo _timezoneInfo;

        Establish context = () =>
        {
            _timezoneInfo = TimeZoneInfoFactory.Create( TimezoneOffset );
            _userType = new TimezoneInfoUserType();
            _command = new SqlCommand();
            _parameterIndex = _command.Parameters.Add( _command.CreateParameter() );
        };

        Because of = () =>
            _userType.NullSafeSet( _command, _timezoneInfo, _parameterIndex );

        It the_offset_is_stored_in_minutes = () =>
            ( (IDataParameter) _command.Parameters[ _parameterIndex ] ).Value.ShouldEqual( TimezoneOffset * 60 );
    }

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_retrieving_a_null_TimezoneInfo
    {
        const string ColumnName = "Timezone";
        static TimeZoneInfo _timezoneInfo;
        static TimezoneInfoUserType _userType;
        static IDataReader _dataReader;

        Establish context = () =>
        {
            _userType = new TimezoneInfoUserType();
            var dataTable = new DataTable();
            dataTable.Columns.Add( ColumnName, typeof( int ) );
            dataTable.LoadDataRow( new object[] {null}, true );
            _dataReader = new DataTableReader( dataTable );
            _dataReader.Read();
        };

        Because of = () =>
            _timezoneInfo = (TimeZoneInfo) _userType.NullSafeGet( _dataReader, new[] {ColumnName}, null );

        It returns_null = () =>
            _timezoneInfo.ShouldBeNull();
    }

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_retrieving_a_TimezoneInfo_with_a_zero_offset
    {
        const string ColumnName = "Timezone";
        static TimeZoneInfo _timezoneInfo;
        static TimezoneInfoUserType _userType;
        static IDataReader _dataReader;

        Establish context = () =>
        {
            _userType = new TimezoneInfoUserType();
            var dataTable = new DataTable();
            dataTable.Columns.Add( ColumnName, typeof( int ) );
            dataTable.LoadDataRow( new object[] {0}, true );
            _dataReader = new DataTableReader( dataTable );
            _dataReader.Read();
        };

        Because of = () =>
            _timezoneInfo = (TimeZoneInfo) _userType.NullSafeGet( _dataReader, new[] {ColumnName}, null );

        It the_BaseUtcOffset_is_zero = () =>
            _timezoneInfo.BaseUtcOffset.TotalHours.ShouldEqual( 0d );

        It the_displayname_is_GMT = () =>
            _timezoneInfo.DisplayName.ShouldEqual( "GMT" );
    }

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_retrieving_a_TimezoneInfo_with_a_positive_offset
    {
        const string ColumnName = "Timezone";
        const int TimezoneOffset = 12;
        static TimeZoneInfo _timezoneInfo;
        static TimezoneInfoUserType _userType;
        static IDataReader _dataReader;

        Establish context = () =>
        {
        _userType = new TimezoneInfoUserType();
        var dataTable = new DataTable();
        dataTable.Columns.Add(ColumnName, typeof(int));
        dataTable.LoadDataRow(new object[] { TimezoneOffset * 60 }, true);
        _dataReader = new DataTableReader(dataTable);
        _dataReader.Read();
        };

        Because of = () =>
            _timezoneInfo = (TimeZoneInfo)_userType.NullSafeGet(_dataReader, new[] { ColumnName }, null);

        It the_BaseUtcOffset_is_generated_from_the_number_of_minutes_retrieved = () =>
            _timezoneInfo.BaseUtcOffset.TotalHours.ShouldEqual( TimezoneOffset );

        It the_displayname_follows_the_pattern_GMT_plus_timezone_offset_ = () =>
            _timezoneInfo.DisplayName.ShouldEqual( "GMT+" + TimezoneOffset );
    }

    [Subject(typeof(TimezoneInfoUserType))]
    public class When_retrieving_a_TimezoneInfo_with_a_negative_offset
    {
        const string ColumnName = "Timezone";
        const int TimezoneOffset = -12;
        static TimeZoneInfo _timezoneInfo;
        static TimezoneInfoUserType _userType;
        static IDataReader _dataReader;

        Establish context = () =>
        {
            _userType = new TimezoneInfoUserType();
            var dataTable = new DataTable();
            dataTable.Columns.Add( ColumnName, typeof( int ) );
            dataTable.LoadDataRow( new object[] {TimezoneOffset * 60}, true );
            _dataReader = new DataTableReader( dataTable );
            _dataReader.Read();
        };

        Because of = () =>
            _timezoneInfo = (TimeZoneInfo) _userType.NullSafeGet( _dataReader, new[] {ColumnName}, null );

        It the_BaseUtcOffset_is_generated_from_the_number_of_minutes_retrieved = () =>
            _timezoneInfo.BaseUtcOffset.TotalHours.ShouldEqual( TimezoneOffset );

        It the_displayname_follows_the_pattern_GMT_minus_timezone_offset_ = () =>
            _timezoneInfo.DisplayName.ShouldEqual( "GMT" + TimezoneOffset );
    }

Categories: NHibernate, TDD, Unit Testing

Managing and Testing Component Registrations with Castle Windsor

September 11, 2009 2 comments

This post is an extension of an earlier post on testing container registrations.  In this post I cover testing again as well as how I manage component registrations to reduce the amount of xml needed and how I automate component registration as much as possible.

First up, the scenario within which I am using a container:

  • ASP.NET MVC application
  • controllers managed via the WindsorControllerFactory from MVCContrib.
  • actions have only 1 parameter and that type is an interface – the container manages the parameter types via a custom model binder.
  • Parameters are 1 of 3 types:
    1. Commands – do something to the domain and return a result that cannot cause side-effects ( ideally immutable but you cannot use structs in views ).
    2. Queries – retrieve data from the system and pack it into a return type that is effectively a view model.
    3. UrlActions – some actions need both commands and queries and must share request state ( form data, query parameters or route parameters ) so until I use special classes that combine commands and queries for this.
  • A custom validation approach that is similar to FluentValidation
  • NHibernate + NHibernateIntegrationFacility + FluentNHibernate

Semi-automatic Component Registration

Using base or marker interfaces allows you to define a few bulk registrations, rather than a large number of fine-grained registrations.  The design of the application outlined above provides four places where I usually add features into the sytem.  Each one of these extension points is identified by a base interface, this makes it easier to find and automatically register the associated components.  The extension points are:

  • Commands – ICommand<T>
  • Queries – IQuery<T>
  • UrlActions – IUrlAction
  • Validators – IValidator<T>

To add a feature ( e.g. logon ), I usually implement a query, a command and two validators.  All of these components are covered by bulk registrations, therefore I don’t have to “remember” to register them in the container before using them – it happens automatically.

public static class ComponentRegistrations
    {
        public static readonly Assembly CommandsAssembly = typeof( RegistrationCommand ).Assembly;

        public static readonly IRegistration Commands =
            AllTypes.Of( typeof( ICommand<> ) )
                .FromAssembly( CommandsAssembly )
                .WithService.Select((t, b) => new List<Type> {t.FindMostSpecificChildInterfaceOf( b )} )
                .Unless( t => t.IsAbstract || t.IsInterface )
                .Configure( c => c.LifeStyle.Transient );
    }

Simple Component Registration Testing

Placing all of the registrations in a class like ComponentRegistrations greatly simplifies unit testing. I use a helper class that converts the single registration defined by AllTypes.Of(...) into individual registrations.

When testing registrations, you only need to test the “extra bits”.  In the above registration that equates to the .WithService.Select(...) bit.  The test looks like this:

    [Specification]
    public class When_registering_commands
    {
        private CompontentRegistrationsTestContext _context;

        public void Given(CompontentRegistrationsTestContext context)
        {
            _context = context;
        }

        public void When()
        {
            _context.WhenRegisteringWith( ComponentRegistrations.Commands );
        }

        [Then]
        public void the_service_should_be_defined_by_the_most_specific_interface_inheriting_from_ICommand()
        {
            _context.AllRegistrations(
                r => r.ServiceType.ShouldEqual(
                         r.Implementation.FindMostSpecificChildInterfaceOf( typeof(ICommand<>)) ) );
        }
    }

The context class that converts the registrations uses an IKernel stub to convert bulk registrations like BasedOnDescriptor into ComponentRegistration instances.

    public class CompontentRegistrationsTestContext
    {
        private List<ComponentRegistration> _registrations;

        public void WhenRegisteringWith( IRegistration registration )
        {
            _registrations = new List<ComponentRegistration>();

            var componentRegistration = registration as ComponentRegistration;
            if( componentRegistration != null )
            {
                // We want to capture the component registrations, not execute them
                _registrations.Add( componentRegistration );
                return;
            }

            // If they are not component registrations, they will be descriptors that
            // generate numerous registrations ( i.e. BasedOnDescriptor )
            var kernel = MockRepository.GenerateStub<IKernel>();
            kernel.Stub( stub => stub.Register( null ) )
                .IgnoreArguments()
                .Callback( new RegisterDelegate( CaptureRegistrations ) )
                .Return( kernel );

            registration.Register( kernel );
        }

        public void AllRegistrations( Action<ComponentRegistration> assertion )
        {
            _registrations.Do( assertion );
        }

        public bool ContainsRegistration( Func<ComponentRegistration, bool> matchCriteria )
        {
            return _registrations.Any( matchCriteria );
        }

        private delegate bool RegisterDelegate(IRegistration[] registrations);
        private bool CaptureRegistrations(IRegistration[] registrations)
        {
            _registrations.AddRange(registrations
                .Select(r => (ComponentRegistration)r));
            return true;
        }
    }

Simplify Complex Component Registrations

Where I need more complex registrations that need to work with the configuration, I write a custom IRegistration implementation. The following example registers a component to intercept and redirect emails being sent from the website.  Usign a custom registration means that I can add all of the configuration required by components to the facility configuration in the simplest possible form, yet still use parameters for configuring components.

    public class RedirectingEmailSenderRegistration : IRegistration
    {
        public const string RedirectingEmailSenderKey = "redirecting.emailsender";
        public const string RedirectConfigurationChildKey = "redirectEmails";
        public const string RedirectConfigurationToAddressKey = "to";
        public const string RedirectConfigurationSkipSendingKey = "skipSending";

        private readonly IConfiguration _configuration;

        public RedirectingEmailSenderRegistration( IConfiguration facilityConfiguration )
        {
            _configuration = facilityConfiguration.Children[RedirectConfigurationChildKey];
        }

        public void Register(IKernel kernel)
        {
            kernel.ConfigurationStore.AddComponentConfiguration(
                RedirectingEmailSenderKey,
                BuildRedirectingEmailSenderConfiguration() );
            kernel.AddComponent(
                RedirectingEmailSenderKey,
                typeof( IEmailSender ),
                typeof( RedirectingEmailSender ),
                LifestyleType.Singleton );
        }

        private IConfiguration BuildRedirectingEmailSenderConfiguration()
        {
            if( _configuration == null )
            {
                throw new ConfigurationErrorsException(
                    "Missing configuration for the redirecting email sender.  Please ensure the following element is present and correct: <redirectEmails to=\"redirect address here\" />" );
            }
            var redirectAddress = _configuration.Attributes[ RedirectConfigurationToAddressKey ];
            if( String.IsNullOrEmpty( redirectAddress ) )
            {
                throw new ConfigurationErrorsException(
                    "Missing configuration for the redirecting email address sender.  Please ensure the to attribute is populated with a valid email address" );
            }
            var skipSending = _configuration.Attributes[ RedirectConfigurationSkipSendingKey ];
            if( String.IsNullOrEmpty( skipSending ))
            {
                skipSending = Boolean.FalseString;
            }
            var configuration = new MutableConfiguration( "component" );
            configuration.Attribute( "id", RedirectingEmailSenderKey )
                .CreateChild( "parameters" )
                .AddChild( "redirectTo", redirectAddress )
                .AddChild( "skipSending", skipSending );

            return configuration;
        }
    }

An additional benefit of this is that you can inspect the result of the registration to ensure it works the way you expect it to.

    [Specification]
    public class When_registering_the_redirecting_email_sender
    {
        private RedirectingEmailSenderRegistration _registration;
        private IKernel _kernel;
        private IConfigurationStore _configurationStore;

        public void Given(DevelopmentContainerConfigurationContext context)
        {
            _registration = new RedirectingEmailSenderRegistration( context.BuildFacilityConfiguration() );

            _kernel = MockRepository.GenerateStub<IKernel>();
            _configurationStore = MockRepository.GenerateStub<IConfigurationStore>();

            _kernel.ConfigurationStore = _configurationStore;
        }

        public void When()
        {
            _registration.Register(_kernel);
        }

        [Then]
        public void the_redirecting_email_sender_is_configured()
        {
            _configurationStore.AssertWasCalled(
                cs => cs.AddComponentConfiguration( null, null ),
                c => c.IgnoreArguments()
                         .Constraints(
                         Is.Equal( RedirectingEmailSenderRegistration.RedirectingEmailSenderKey ),
                         Is.Anything() ) );
        }

        [Then]
        public void the_redirecting_email_sender_is_registered()
        {
            _kernel.AssertWasCalled(
                k => k.AddComponent(
                         RedirectingEmailSenderRegistration.RedirectingEmailSenderKey,
                         typeof( IEmailSender ),
                         typeof( RedirectingEmailSender ),
                         LifestyleType.Singleton) );
        }
    }

Simplify Management of Component Registrations

Generally when I am developing a web application, I have two sets of components that I need to manage, one set for production – the components that make up the actual application, and a second set for development that perform tasks like redirecting the email from the application into a specific email address.

Rather than having to remember which components belong to what set, I create two facilities to register the components, the first is <ApplicationName>ConfigurationFacility and the second is DevelopmentConfigurationFacility. Because all the registrations can be accessed via static members of the ComponentRegistrations class I can create a simple facility as shown below.  This means it is easy to see what components are being registered in the container and in what order ( you can also register facilities in the same way ):

    public class DevelopmentConfigurationFacility : AbstractFacility
    {
        protected override void Init()
        {
            Kernel.Register( DevelopmentComponentRegistrations.DatabaseController );
            Kernel.Register( DevelopmentComponentRegistrations.RedirectingEmailSender( FacilityConfig ) );
            Kernel.Register( DevelopmentComponentRegistrations.NHibernateProfilerInitialisingConfigurationBuilder );
            Kernel.Register( DevelopmentComponentRegistrations.EnableStatisticsPersistenceConfigurer );
            Kernel.Register( DevelopmentComponentRegistrations.ShowSqlPersistenceConfigurer );
        }
    }

By using facilities to group component registrations, I can effectively “bootstrap” the container into one of two modes ( development or production ) by adding or removing one facility registration ( instead of 5 component registrations + the associated component configuration ).

Careful thought about the strategies you use to manage and test your component registrations may cost you some time up front, but it is time well invested as once it is up and running, you should end up with a zero-friction environment wrt components.

If it just works and you don’t notice when it does – you’ve done it right

Creating entities in unit tests

August 23, 2009 1 comment

An interesting question came up on twitter a moment ago about creating entities for unit tests, what follows is the approach that I use to enable me to create entities with the minimum possible code yet the maximum possible flexibility.

I have two entities Account and User, the code for them is shown below.


    public class Account : Entity<Account>
    {
        public Account( string accountName )
        {
            Name = accountName;
            Users = new List<User>();
            Questionnaires = new List<Questionnaire>();
        }

// ReSharper disable UnusedMember.Local
        private Account()
        {
            // Required by NHibernate
        }
// ReSharper restore UnusedMember.Local

        public string Name { get; private set; }
        public User Owner { get; private set; }
        public IList<User> Users { get; private set; }
        public IList<Questionnaire> Questionnaires { get; private set; }

        public User CreateUser( string username, string passphrase, string name, string emailAddress, string country, string timezone, bool asOwner )
        {
            var user = new User( username, passphrase, name, emailAddress, country, timezone, this );
            Users.Add( user );
            if( asOwner )
            {
                Owner = user;
            }

            return user;
        }

        public Questionnaire CreateQuestionnaire( string name )
        {
            Contract.Requires( () => name );
            var questionnare = new Questionnaire( name, this );
            Questionnaires.Add( questionnare );
            return questionnare;
        }
    }

    public class User : Entity<User>
    {
        public const int MaxAuthenticationRetryCount = 5;

        public User( string username, string passphrase, string name, string emailAddress, string country, string timezone, Account account )
        {
            Contract.Requires( () => username );
            Contract.Requires( () => passphrase );
            Contract.Requires( () => name );
            Contract.Requires( () => emailAddress );
            Contract.Requires( () => country );
            Contract.Requires( () => timezone );
            Contract.Requires( () => account );
            Username = username;
            Passphrase = passphrase;
            Name = name;
            EmailAddress = emailAddress;
            Country = country;
            Timezone = timezone;
            Account = account;
            EmailAddressConfirmed = false;
        }

// ReSharper disable UnusedMember.Local
        private User()
        {
            // Required by NHibernate
        }
// ReSharper restore UnusedMember.Local

        public string Username { get; private set; }
        public string Passphrase { get; private set; }
        public string Name { get; private set; }
        public string EmailAddress { get; private set; }
        public string Country { get; private set; }
        public string Timezone { get; private set; }
        public Account Account { get; private set; }
        public bool EmailAddressConfirmed { get; private set; }
        public int AuthenticationRetryCount { get; private set; }

        public void ConfirmEmailAddress()
        {
            EmailAddressConfirmed = true;
        }

        public bool Authenticate( string passphrase )
        {
            Contract.Requires( () => passphrase );
            if (IsAccountLocked())
            {
                return false;
            }

            var isAuthenticated = String.Compare( Passphrase, passphrase, StringComparison.InvariantCulture ) == 0;
            if (isAuthenticated)
            {
                AuthenticationRetryCount = 0;
            }
            else
            {
                AuthenticationRetryCount += 1;
            }

            return isAuthenticated;
        }

        public bool IsAccountLocked()
        {
            return AuthenticationRetryCount >= MaxAuthenticationRetryCount;
        }

        public void ResetPassphrase( string newPassphrase )
        {
            Contract.Requires( () => newPassphrase );
            Passphrase = newPassphrase;
        }

        public void UnlockAccount()
        {
            AuthenticationRetryCount = 0;
        }
    }

To manage creation of these entities during testing I have a static factory class for each that manages creating the entities and optionally populating any properties ( often using reflection ). The source for these is as follows:

    public static class AccountFactory
    {
        public static Account Create()
        {
            var account = new Account( "Account Name" );
            UserFactory.Create( account, true );
            return account;
        }
    }

    public static class UserFactory
    {
        public static User Create()
        {
            var account = AccountFactory.Create();
            return Create( account, true );
        }

        public static User Create( Account account, bool asOwner )
        {
            var user = account.CreateUser( "Username", "a valid passphrase", "Name", "email@address.com", "New Zealand", "GMT+12", asOwner );
            return user;
        }

        public static User WithUsername( this User user, string username )
        {
            user.SetPropertyValue( u => u.Username, username );
            return user;
        }

        public static User WithPassphrase( this User user, string passphrase )
        {
            user.SetPropertyValue( u => u.Passphrase, passphrase );
            return user;
        }

        public static User WithEmailAddress( this User user, string emailAddress )
        {
            user.SetPropertyValue( u => u.EmailAddress, emailAddress );
            return user;
        }

        public static User MimicFailedAuthenticationAttempts( this User user, int failedAttempts )
        {
            user.SetPropertyValue( u => u.AuthenticationRetryCount, failedAttempts );
            return user;
        }

        public static User MimicLockout( this User user)
        {
            user.SetPropertyValue( u => u.AuthenticationRetryCount, User.MaxAuthenticationRetryCount );
            return user;
        }
    }

The create methods return a valid entity initialised with a default set of values that can be used for testing any scenario you like. If you need to customise the data in the entities to fit a specific test scenario, the extension methods allow additional tweaking of the entity data ( often via reflection ).

This approach allows me to build entities quickly for testing purposes while ensuring that I don’t have to maintain a God class that manages building many different entities and their relationships, it is essentially convention over configuration for my entities.

Categories: c#, Unit Testing

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<...>().

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

Unit Testing MonoRail Controllers with PrincipalPermissions

March 19, 2008 3 comments

When you apply a CodeAccessSecurityAttribute that returns a PrincipalPermission to an action on a controller, all your existing tests for that action will break (to find out more about applying principal permissions, take a look at this blog entry about creating clean principal permission attributes). After a bit of digging and a lot of googling, I came across this post by Phil Haack that demonstrates how to set up your unit tests so they run correctly again.

Phil’s approach uses Rhino Mocks to mock out the IPrincipal and IIdentity interfaces and then attaches the mocked IPrincipal to Thread.CurrentPrincipal (which is where the PrincipalPermission retrieves the principal from to check permissions against). This approach is great, however I rapidly got tired of having to write out all of the code that this approach required, and I was getting annoyed with the clutter of try / finally blocks inside my tests (as well as forgetting to put the MockRepository into replay mode numerous times), so I stubbed out the principal and identity to create a much simpler alternative to the mocked versions. You can see these classes below:

    public class PrincipalStub : IPrincipal
{
    private readonly string _name;
    private readonly string _authenticationType;
    private readonly bool _isAuthenticated;
    private readonly bool? _isInRoleResponse;
    private readonly List<string> _roles;

    public PrincipalStub( string name, string authenticationType, bool isAuthenticated, bool isInRoleResponse )
    {
        _name = name;
        _isAuthenticated = isAuthenticated;
        _authenticationType = authenticationType;
        _isInRoleResponse = isInRoleResponse;
    }

    public PrincipalStub( string name, string authenticationType, bool isAuthenticated, params string[] roles )
    {
        _name = name;
        _isAuthenticated = isAuthenticated;
        _authenticationType = authenticationType;
        _roles = new List<string>( roles );
    }

    public IIdentity Identity
    {
        get
        {
            return new IdentityStub( _name, _authenticationType, _isAuthenticated );
        }
    }

    public bool IsInRole( string role )
    {
        if ( _isInRoleResponse.HasValue )
        {
            return _isInRoleResponse.Value;
        }

        return _roles.Contains( role );
    }
}

public class IdentityStub : IIdentity
{
    private readonly string _name;
    private readonly string _authenticationType;
    private readonly bool _isAuthenticated;

    public IdentityStub( string name, string authenticationType, bool isAuthenticated )
    {
        _name = name;
        _isAuthenticated = isAuthenticated;
        _authenticationType = authenticationType;
    }

    public string Name
    {
        get
        {
            return _name;
        }
    }

    public string AuthenticationType
    {
        get
        {
            return _authenticationType;
        }
    }

    public bool IsAuthenticated
    {
        get
        {
            return _isAuthenticated;
        }
    }
}

This means I can now replace the mocks and all the associated setup with a single line of code:
IPrincipal testPrincipal = new PrincipalStub("Test", "Test", true, true);

which will create a new principal that is always in any role asked of it (remember we want to test the action, not the code access security). This still left me with the setup and teardown code that I could have put into appropriate methods in the test class, but that lacked the flexibility to specify the exact parameters of the PrincipalStub for each test, and meant that all of my tests would be running under a “false” principal – less than ideal.What I needed was a mechanism for performing a two-phase operation with a chunk of indeterminate code in the middle, and the guarantee that the second phase would always run. Delegates and anonymous methods could have worked, but I got my inspiration from an approach Oren Eini (Ayende) uses to provide a more explicit mocking syntax. Taking this and applying it to the scenario I had resulted in the following TestPrincipalManger:

public class TestPrincipalManager
{
    private PrincipalStub _principal;

    public TestPrincipalManager(string username, string authenticationType, bool isAuthenticated, params string[] roles)
    {
        _principal = new PrincipalStub(username, authenticationType, isAuthenticated, roles);
    }

    public TestPrincipalManager(string username, string authenticationType, bool isAuthenticated, bool isInRoleResponse)
    {
        _principal = new PrincipalStub(username, authenticationType, isAuthenticated, isInRoleResponse);
    }

    public IDisposable Attach()
    {
        IPrincipal originalPrincipal = Thread.CurrentPrincipal;
        Thread.CurrentPrincipal = _principal;
        return new TestPrincipalCleanup( originalPrincipal );
    }

    public class TestPrincipalCleanup : IDisposable
    {
        private readonly IPrincipal _principal;

        public TestPrincipalCleanup( IPrincipal principal )
        {
            _principal = principal;
        }

        public void Dispose()
        {
            Thread.CurrentPrincipal = _principal;
            GC.SuppressFinalize( this );
        }
    }
}
That can be used as follows:

[Test]
public void AdministratorPermissionAttribute_Permission_Succeeds_If_Principal_Does_Have_Administrator_Permission()
{
    TestPrincipalManager authorisedPrincipal = new TestPrincipalManager("A.User", "Test Auth", true, "Administrator");
    AdministratorPermissionAttribute permissionsAttribute = new AdministratorPermissionAttribute( SecurityAction.Demand );
    IPermission permission = permissionsAttribute.CreatePermission();

    using ( authorisedPrincipal.Attach() )
    {
            Assert.IsTrue(Thread.CurrentPrincipal.IsInRole("Administrator"), "Pre-condition failed: Current user does not have the Administrator permission");
            permission.Demand();
    }
}
While at first glance, this appears to be a perversion of the using syntax / IDisposable interface, if you take a second look it makes perfect sense. Using is essentially just a compiler macro that replaces the using with a try / finally, and the object that we are disposing of is following the semantics of the dispose operation – it is cleaning up after itself. Extracting the class doing the disposal out means that the Attach() method can be called repeatedly with no nasty side-effects (I hope!).

Categories: MonoRail, Unit Testing

Using a Domain Model Simplifies Your Unit Testing

March 18, 2008 Leave a comment

I’ve just had one of those AHA! moments – you know, when you are staring at code and you have a bunch of concepts running around the back of your mind and something just falls into place.

The code I happened to be staring at was a set of unit tests for my UserController, and the tests simply ensured the basic user management operations worked as they should (user is created, user is updated etc etc). For some reason while I was staring at this I was thinking about testing that the newly created users could log in successfully, but what that would really be testing was are the users created correctly?

This kind of thinking comes from my days before unit testing, domain objects and DRY, back then the code that created the user would be quite separate from the code that logged the user in and both of these actions would have a significant “plumbing” code in them meaning that if we changed something about the way the user was created, we could conceivably break the login process without knowing it (a lot of the applications I used to build were highly procedural / transaction script oriented), so I would have something like (warning: aircode):

public bool Login(string username, string password)
{
    DataRow userRow = UserDAO.GetUser( username );
    return userRow["Password"] == password;
}
… somewhere else in the app …

public void CreateUser(string username, string password, ... )
{
    UserDAO.CreateUser(username, password, ... );
}
So what would happen if the boss suddenly decreed that all passwords should be stored with hashes? I’d definately change the CreateUser code, but what if I didn’t write the Login code, would I know about it? Without unit tests, definitely not; with unit tests, maybe, depending on how much was mocked out (as ideally I wouldn’t be testing the data access code so my mock would return what I was expecting). Compare that to my current implementation – a Credentials class that contains all of the username / password / login attempts related details (and nothing about persistence):

    public class Credentials
    {
        public const int MaximumLoginAttempts = 3;

        private string _username;
        private readonly HashedPassword _password;
        private int _loginAttemptsRemaining;

        public string Username
        {
            get
            {
                return _username;
            }
        }

        public int LoginAttemptsRemaining
        {
            get
            {
                return _loginAttemptsRemaining;
            }
        }

        public bool IsLockedOut
        {
            get
            {
                return _loginAttemptsRemaining  MaximumLoginAttempts)
            {
                loginAttemptsRemaining = MaximumLoginAttempts;
            }

            _loginAttemptsRemaining = loginAttemptsRemaining;
        }

        public bool ValidatePassword(string password)
        {
            if (_loginAttemptsRemaining <= 0)
            {
                return false;
            }

            if (_password.IsSameAs(password))
            {
                _loginAttemptsRemaining = MaximumLoginAttempts;
                return true;
            }

            _loginAttemptsRemaining = _loginAttemptsRemaining - 1;
            return false;
        }
    }
This implementation already stores the data as a hashed password, but the original version didn’t (only for the first version where I was concentrating on getting the basic behaviours). Adding the ability to hash the password didn’t change the external interface in any way and therefore any existing tests I had didn’t require any changes – they just worked.

It is not so much that using a domain model directly simplifies your unit testing, it’s more that a domain model encourages you to implement separation of concerns and the single responsibility principle. SoC and SRP combine to significantly increase the testability of your application (as well as decreasing the fragility of the unit tests).

In my case, the true realisation was that because the responsibility for the persistence of the object was separate from the user object and the controller, I couldn’t break the login code by changing the persistence code or the user creation code (assuming I created a valid user object), and because I had previously tested the login code, I had already tested the login code under all of the scenarios that were applicable.

Building a domain model is definitely worth the effort!

Follow

Get every new post delivered to your Inbox.