Archive

Archive for the ‘c#’ Category

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

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

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

Making session variables a little easier to work with

May 29, 2008 4 comments

It’s been quiet on here for a while – that’s because I’ve been warped back to WebForms land where everything is craziness and it takes you half a day just to figure out wth is going on because you have to work with logic spread across a half dozen code behind files that all run to a couple thousand lines (no exaggeration!).

The app I am currently working on uses session variables a lot, and doesn’t clean them up very often, leading to odd behaviors due to stale state (among other things).

The first thing I do when I come across a page using session variables is extract them all into properties at the top of the page – this ensures those ugly string indexers are only in 2 places (the get and set) and you only have to write the cast once.  The problem I find with this is that to figure out if the session variable has a value or clean up the session variable I still have to address it using the string indexer, sure I can wrap that in a simple method call so I only have the indexer in 3 or 4 places, but when you have a page with 6 session variables, this starts to add a lot of cruft to the code behind.  What I really wanted was a simple way of adding a few methods to the property so I could do something like this…

int newValue = 0;
if( MySessionVar.HasValue )
{
  newValue += MySessionVar;
}
MySessionVar.Clear();

With a little bit of poking around, some generics and a simple implicit cast, I ended up with this:

using System;
using System.Web;

namespace Blog.Code
{
    ///<summary>
    /// Wraps a number of convenience methods around session variables allowing for a more fluent
    /// expression of the intent.
    ///</summary>
    ///<typeparam name="T">The type of the value to store in the session.</typeparam>
    public class SessionVariable<T> : IEquatable<SessionVariable<T>>
    {
        private readonly T _tempValueStore;
        private readonly string _sessionKey;

        ///<summary>
        /// The stored value or the default value for the type
        /// if there is no value associated with the sessionkey
        ///</summary>
        public T Value
        {
            get
            {
                object value = HttpContext.Current.Session[_sessionKey];
                if(value == null)
                {
                    return default( T );
                }

                return (T)value;
            }
        }

        ///<summary>
        /// Indicates if there is a value stored.
        ///</summary>
        public bool HasValue
        {
            get
            {
                return HttpContext.Current.Session[ _sessionKey ] != null;
            }
        }

        ///<summary>
        /// Creates a new SessionVariable to access the value stored in <paramref name="sessionKey"/>
        ///</summary>
        ///<param name="sessionKey">The key used to access the value in the session</param>
        public SessionVariable( string sessionKey )
        {
            _sessionKey = sessionKey;
        }

        ///<summary>
        /// Creates a new SessionVariable to store the value provided.
        ///</summary>
        ///<param name="value">The value to store.</param>
        /// <remarks>
        /// Value is not stored until <see cref="Store"/> is called.
        /// </remarks>
        public SessionVariable( T value )
        {
            _tempValueStore = value;
        }

        ///<summary>
        /// Stores the value in the session using the key specified.
        ///</summary>
        ///<param name="sessionKey">The key used to store the value.</param>
        public void Store(string sessionKey)
        {
            HttpContext.Current.Session[ sessionKey ] = _tempValueStore;
        }

        ///<summary>
        /// Removes the entry from the session.
        ///</summary>
        public void Clear()
        {
            HttpContext.Current.Session.Remove( _sessionKey );
        }

        ///<summary>
        /// Implicitly converts the specified value into a SessionVariable instance.
        ///</summary>
        ///<param name="value">The value to convert.</param>
        ///<returns>A SessionVariable instance holding the specified value.</returns>
        public static implicit operator SessionVariable<T>(T value)
        {
            return new SessionVariable<T>( value );
        }

        ///<summary>
        /// Implicitly converts the SessionVariable back to the type of the wrapped value.
        ///</summary>
        ///<param name="sessionVariable">The SessionVariable to convert</param>
        ///<returns>The wrapped value.</returns>
        public static implicit operator T(SessionVariable<T> sessionVariable)
        {
            return sessionVariable.Value;
        }

        public override string ToString()
        {
            return Value.ToString();
        }

        public bool Equals( SessionVariable<T> sessionVariable )
        {
            if ( sessionVariable == null )
            {
                return false;
            }
            return Equals( Value, sessionVariable.Value );
        }

        public override bool Equals( object obj )
        {
            if ( ReferenceEquals( this, obj ) )
            {
                return true;
            }
            return Equals( obj as SessionVariable<T> );
        }

        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }
    }
}

Which can be used like this:

protected SessionVariable<string> SuccessMessage
{
    get
    {
        return new SessionVariable<string>("SuccessMessage");
    }
    set
    {
        value.Store("SuccessMessage");
    }
}

The only caveat is when accessing methods on the object you are wrapping, you have to use 1 of 2 approaches to get at the underlying value…

// Directly access the underlying value
SuccessMessage.Value.Split(...);

// Assign the wrapped value to a temporary variable to force the implicit cast
string successMessage = SuccessMessage;
successMessage.Split(...);

As the session is really just a Dictionary<string, object> you could probably make this work for any dictionary with a few simple changes, however I didn’t need that flexibility so I leave it as an exercise for the future.

Categories: c#, WebForms

Creating Clean Principal Permission Attributes

March 18, 2008 1 comment

MonoRail allows you to use the PrincipalPermissionAttribute to secure your code in a reasonably unobtrusive manner as shown in the MonoRail documentation here. This is great as it allows a simple way to express the security requirements of your actions without cluttering the action with security checks. This problem I have with this is it adds a rather ugly attribute to the action that looks like:

[PrincipalPermission(SecurityAction.Demand, Role='Administrator')]
public void DoSomeAdminStuff()
{
    // ...
}
I also have to remember exactly how to type it out if I want to reuse it, so I set out to create a “nice” attribute that would communicate the same information with a lot less clutter – something like:

[RequireAdministratorPermission]
public void DoSomeAdminStuff()
{
    // ...
}
A quick bit of digging shows that the PrincipalPermissionAttribute is sealed so I can’t apply my usual trick of extending it and providing the default values I want, so I set about figuring out exactly what the PrincipalPermissionAttribute does. Turns out it is very simple, just extend the CodeAccessSecurityAttribute and implement IPermission CreatePermission(). Poking around in the PrincipalPermissionAttribute just to make sure I was doing things correctly, showed that I need to check if the underlying SecurityAttribute had it’s Unrestricted flag set and return an unrestricted permission if it was, so I extracted this into a superclass to simplify creating additional permission attributes later. The resulting classes are very simple and do not do much at all (except make my code look a lot nicer!).

public abstract class BasePrincipalPermissionAttribute : CodeAccessSecurityAttribute
{
    protected BasePrincipalPermissionAttribute( SecurityAction action ) : base( action )
    {
    }

    public override IPermission CreatePermission()
    {
        if (Unrestricted)
        {
            return new PrincipalPermission(PermissionState.Unrestricted);
        }

        return CreatePrincipalPermission();
    }

    protected abstract PrincipalPermission CreatePrincipalPermission();
}

public class AdministratorPermissionAttribute : BasePrincipalPermissionAttribute
{
    public ManageUsersPermissionAttribute( SecurityAction action ) : base( action )
    {
    }

    protected override PrincipalPermission CreatePrincipalPermission()
    {
        return new PrincipalPermission( null, "Administrator", true );
    }
}

And they can be used like:

[AdministratorPermission(SecurityAction.Demand)]
public void DoSomeAdminStuff()
{
    // ...
}

Unfortunately you still have to specify the security action, this is due to something that occurs during the compile process to serialise the permissions and store them with the assembly requiring the SecurityAction to be specified in the constructor of the attribute.

Categories: c#, MonoRail

A Simple IComparer Decorator to Add Sort Ordering

March 14, 2008 Leave a comment

Today I needed to implement some sorting over domain objects based on the following rules:

  • Surveys must be sorted by their age (effective date – generally the date the survey was created)
  • Priority surveys must appear at the top of the list

So I set out an encapsulated these rules into a nice class that implemented IComparer<T>. The single method of this interface int Compare(T x, T y) should return an integer according to the following rules:

  • If x is less than y, return an int less than 0
  • If x is equal to y, return 0
  • If x is greater than y, return an int greater than 0

Writing this up, we end up with a pretty simple encapsulation of the comparison rules than make pretty good sense:

// Priority > Normal
if (left.IsPriority != right.IsPriority)
{
    if (left.IsPriority)
        return 1;
    else
        return -1;
}

// Older Effective Date > Newer Effective Date
if(left.EffectiveDate > right.EffectiveDate)
{
    return -1;
}

if(left.EffectiveDate < right.EffectiveDate)
{
    return 1;
}

return 0;
The problem is, when I view the sorted result, my priority surveys are at the bottom of the list, a bit of digging and I find out that by default List<T>.Sort(IComparer<T>) returns the list sorted in descending order.

I could correct this by simply changing the returned values to return the inverse of the value (i.e. 1 becomes -1 and vice versa), however that would distort the meaning of the comparison (priority survey > normal survey and older survey > newer survey). A better approach is to add the sort ordering after the comparison, even better, we can completely separate the ordering from the comparison by decorating the comparer with another class that implements the sort ordering logic. This leads to the SortOrderComparer<T> shown below:

public enum CompareSortOrder
{
    Descending,
    Ascending
}

public class SortOrderComparer<TEntity> : IComparer<TEntity>
{
    private readonly IComparer<TEntity> _innerComparer;
    private readonly CompareSortOrder _sortOrder;

    public SortOrderComparer( IComparer<TEntity> innerComparer, CompareSortOrder sortOrder )
    {
        _innerComparer = innerComparer;
        _sortOrder = sortOrder;
    }

    public int Compare( TEntity x, TEntity y )
    {
        int result = _innerComparer.Compare( x, y );
        if(_sortOrder == CompareSortOrder.Descending)
        {
            return result;
        }

        return result * -1;
    }
}
Now we can apply sort ordering to any comparer quickly and simply:

IComparer<MyClass> sortingComparer = new SortOrderComparer( new MyComparer(), CompareSortOrder.Ascending );
list.Sort( sortingComparer );
I wouldn’t be surprised if this has been done somewhere else as it is reasonably obvious (only took me a few days to see it!) :) .

Categories: c#
Follow

Get every new post delivered to your Inbox.