Monday, March 11, 2013

Building a Service App: Logging

Preface

In the last post, we saw how to get started hooking things up with Windsor, TopShelf, and NLog. This post will take a look at logging with Windsor and NLog. We'll also look at using a utility called Log2Console to view our log messages as they are generated.

The Packages

This post looks at using the following NuGet packages:
Installing Castle.Windsor-NLog ensures that all the appropriate logging dependencies are included in our application. NLog.Schema adds some Intellisense to help with the NLog.config file.

Initializing the Logger

Windsor's behavior can be extended through the use of facilities. A handy one, available out of the box, is the Logging Facility. We'll be setting up to use NLog as our framework. Windsor is configured to use NLog by adding the appropriate facility:

            container.AddFacility<LoggingFacility>(facility => facility.LogUsing(LoggerImplementation.NLog))

It is possible to specify various options: config file location, log target, etc. We'll be using the default NLog beahvior which looks for a file called NLog.config in the root directory of the assembly.

Configuring the Logger

Adding the NLog.Schema package to a project adds a schema file which can aid in editing the NLog.config file. The NLog wiki is pretty good about documenting the different options. In short, the config is broken into two sections:

  1. Targets. These describe the formatting, content, and destination of the log message.
  2. Rules. These describe what gets logged, and to what target the message is sent.
Viewing Logger Messages

A nifty trick which can be used while you're working on things is to use NLog in conjunction with a utility called Log2Console. To use Log2Console to view log message, you will need to add a receiver. This will allow it to receive messages. First click the Receivers button, then click the Add... button. Add a UDP receiver, leaving the default settings.

The receivers dialog box with a UDP receiver added.

After adding the receiver, the NLog.config file will need to be updated. A Chainsaw target will need to be added. There will also need to be the corresponding rule created:

A snapshot of an NLog.config file highlighting the chainsaw config options.


Once it's setup, Log2Console should catch the messages sent to NLog by your application.

An example of log output in Log2Console.


Conclusion

This showed a quick and dirty way of viewing log messages in real time. It's something that could be useful while working on applications. Next up will be a look at setting up WCF endpoint in our TopShelf app.

Thursday, March 7, 2013

Building a Service App: Adding Windsor and TopShelf

Preface

In the last post we started with a basic exception handling clause in our console application. This time, we'll be dropping in TopShelf, Windsor, and some Logging bits. The example code is available on GitHub.

The Service Class

The service class will be very simple to start. All it will do is write a couple messages to our logger:

    public interface IExampleService
    {
        void Start();
        void Stop();
    }

    public class ExampleService : IExampleService
    {
        private readonly ILogger logger;

        public ExampleService(ILogger logger)
        {
            this.logger = logger;
        }

        public void Start()
        {
            logger.Debug("The service was started.");
        }

        public void Stop()
        {
            logger.Debug("The service was stopped.");
        }
    }

To make this class available elsewhere, we'll need to register it with our IoC container, Windsor. There are a lot of different ways to register components. This time, we'll use an installer. Installers are a convenient way to segregate the registration of your application's components.

    public class MyInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(
                Component.For<IExampleService>().ImplementedBy<ExampleService>()
                );
        }
    }


We'll need to add other components to this as things go along. But for now, it's a good start.

Updating Program.Main()

Now that we have a service class and an installer we can modify the Program.Main() method.

        static void Main()
        {
            try
            {
                var container = ContainerFactory();

                RunTheHostFactory(container);
            }
            catch (Exception exception)
            {
                var assemblyName = typeof(Program).AssemblyQualifiedName;

                if (!EventLog.SourceExists(assemblyName))
                    EventLog.CreateEventSource(assemblyName, "Application");

                var log = new EventLog { Source = assemblyName };
                log.WriteEntry(string.Format("{0}", exception), EventLogEntryType.Error);
            }
        }

The ContainerFactory() method creates a new instance of the container. It then configures the container with the appropriate services.

        private static IWindsorContainer ContainerFactory()
        {
            var container = new WindsorContainer()
                .Install(Configuration.FromAppConfig())
                .Install(FromAssembly.This());
            return container;
        }

The next method, RunTheHostFactory(), covers the bulk of the TopShelf implementation. It uses the TopShelf HostFactory static class to perform the actual work.


        private static void RunTheHostFactory(IWindsorContainer container)
        {
            HostFactory.Run(config =>
                {
                    config.Service<IExampleService>(settings =>
                        {
                            // use this to instantiate the service
                            settings.ConstructUsing(hostSettings => container.Resolve<IExampleService>());
                            settings.WhenStarted(service => service.Start());
                            settings.WhenStopped(service =>
                                {
                                    // stop and release the service, then dispose the container.
                                    service.Stop();
                                    container.Release(service);
                                    container.Dispose();
                                });
                        });

                    config.RunAsLocalSystem();

                    config.SetDescription("This is an example service.");
                    config.SetDisplayName("My Example Service");
                    config.SetServiceName("MyExampleService");
                });
        }

TopShelf's HostFactory use our container to instantiate our service. It also cleans up when the service is stopped. This is the basic TopShelf implementation. Calls to .WhenPaused(), and .WhenContinued() can be added to the HostFactory to handle when the service is paused and resumed in the service control panel.

First Run

At this point it's possible to build and install our service. A handy thing about TopShelf is that it greatly simplifies using generic services. Running our service from the Visual Studio debugger shows us we have some basic functionality (red tic marks indicate the logger entries made by the service class):

The console app being run in the debugger.

There are some other basic things we can do with a TopShelf-based application. We can run the executable as any other console app can be run:

TopShelf app being run as a console app.

Installing the service is pretty done by adding a parameter, install, to the command:

Output of the WcfExample.exe install command.

Once a service is installed, it can be started and stopped:

Example of the WcfExample.exe start command.

Example of the WcfExample.exe stop command.

Finally, the service may be uninstalled:

Example of the WcfExample.exe uninstall command.

Conclusion

We covered how to get started with TopShelf. We also looked at setting up an IoC to work with a TopShelf-based application. Next we'll look a little more at logging, and how we can use a component to configure our service.

Tuesday, March 5, 2013

Building a Service App: Intro & Unhandled Exceptions

Introduction

We do a lot of service applications where I work. Most of them are self-hosted. That means a lot of console-style apps. This post is to document some of the stuff we're doing, so we have something of a common template.

We'll be using a few tools/technologies:
The example code will be hosted on GitHub.

We'll get started with a basic unhandled exception handler. This will give us a way to capture the error when the application won't even start, and hasn't had time to initialize the logging framework.

Program.Main() and Unhandled Exceptions

When everything fails, including your logging mechanism, it's nice to know what happened. There's just a ton of things that can and do go wrong. One way to help catch these errors is to log to the an event log.

    public class Program
    {
        static void Main()
        {
            try
            {
                // do something
            }
            catch (Exception exception)
            {
                var assemblyName = typeof(Program).AssemblyQualifiedName;

                if (!EventLog.SourceExists(assemblyName))
                    EventLog.CreateEventSource(assemblyName, "Application");

                var log = new EventLog { Source = assemblyName };
                log.WriteEntry(string.Format("{0}", exception), EventLogEntryType.Error);
            }
        }
    }

What we've done is place a generic exception handler in the Main() method. It catches generic exceptions, logging them all to the event log. This catches anything that hasn't been caught; your basic unhandled exception handler. Now we have a way to see what happened...

An image showing the error in the Application Windows Log.
The EventLog


A picture of the actual error, complete with stack trace.
The captured error message.

Next...

There you have it. An easy way to capture exceptions when the worst happens. Next up, we'll take a look at dependency injection with Windsor.



Friday, February 22, 2013

PowerShell and TopShelf

Preface

A large part of our development involves generic services. TopShelf simplifies the installation and operation of the services we've been creating. When dealing with a number of services, it can still be a pain to install and start each individual service. To ease that pain point, we created a simple PowerShell script to help.

Deploying the Services

One project involved creating a set of services which were passing messages via RabbitMQ. Setting up a server (test or otherwise) involved dropping 3-6 services in a directory, configuring them, and starting them up. The deployment would be similar to the following:

/Parent Directory
    TopShelfHelper.ps1
    /ServiceA Directory
        topshelfhost.exe
        ... (Other Files)
    /ServiceB Directory
        topshelfhost.exe
        ... (Other Files)

The Script

The script is available on GitHub. Here it is for reference:

param(
 [parameter(mandatory=$true)]
 [validateset("start","stop","uninstall", "install")]
 $command
)

$ErrorActionPreference = "Stop"

push-Location

try
{
 get-ChildItem -Path $pwd -Recurse |
  where-Object {$_.name -eq 'topshelfhost.exe'} |
  select-Object fullname |
  foreach-object {& $_.fullname $command}

 "INFO: Operation completed successfully."
}
catch
{
 $Error[0]
 "ERROR: An error occurred performing the operation."
}
finally
{
 pop-Location
}

This script uses Get-ChildItem to look through all the directories in the current directory. When it finds the appropriate .exe file, it executes the TopShelf command on it. This example script uses the name 'topshelfhost.exe' to as the TopShelf enabled app.

Using the script is pretty easy. Just pass it one of the TopShelf commands (start, stop, install, uninstall), and it handles the rest. Here's an example...


Summary

Not the cleanest of scripts, but an example of you PowerShell can be used to ease some other tasks.

Monday, November 19, 2012

NHibernate: One-to-One Mapping With Shared Key

Preface

A reader commented on a different NHibernate post, asking about how one might do some different mappings. This post describes one of those scenarios: One-to-One mappings with a shared key. In this case, the parent entity has a surrogate key. The child is using the same value as its primary key and the same field as the foreign key to the parent.

Code samples for this article are on Github.

The Database

The test project is setup to run against a SQL Server database rather than some in-memory or mocked instance. I've created a quick SQL script to setup the datbase tables. SQL Server 2008 R2 was used for this example. The Express edition should work equally as well. We will be working with two tables:


The UserDetail.UserId is the same value as User.Id. Both are primary keys. There is a one-to-one relationship between the Users table and the UserDetail table. The UserDetail table, you will note, does not have an independent field for the foreign key.

The User Object

The first entity is the User. The User is the parent object. It is defined as follows. The AddDetail method is used to associate the different entities with each other. For example, if we have a new User and a new UserDetail, we can pass the UserDetail into the User.AddDetail() method. This will ensure that the UserDetail is correctly setup as the child of the User.

    public class User
    {
        public virtual long Id { get; set; }
        public virtual string Name { get; set; }
        public virtual UserDetail Detail { get; set; }

        public virtual void AddDetail(UserDetail userDetail)
        {
            Detail = userDetail;
            Detail.AddUser(this);
        }
    }

The User object's mapping is pretty basic. It sets the identity column as being generated by the database. It also sets the one-to-one mapping for the detail.

    public class UserMap : ClassMapping<User>
    {
        public UserMap()
        {
            Table("Users");

            Id(user => user.Id, mapper => mapper.Generator(Generators.Identity));

            Property(user => user.Name);

            OneToOne(user => user.Detail,
                     mapper =>
                     {
                         mapper.ForeignKey("FK_User_Id");
                         mapper.Cascade(Cascade.All);
                     });
        }
    }

The UserDetail Object

Next up is the UserDetail. UserDetail is a child of User, having a one-to-one relationship with its parent. The UserDetail.AddUser() method performs a similar function to the User.AddDetail() method: it helps setup the association between the UserDetail object and a parent User object. The Equals() and GetHashCode() overrides are necessary to accommodate the way we'll be setting up the mapping.

    public class UserDetail
    {
        public virtual long UserId { get; set; }
        public virtual string DriversLicense { get; set; }
        public virtual bool IsDonor { get; set; }
        public virtual User ParentUser { get; set; }

        public virtual void AddUser(User user)
        {
            ParentUser = user;
            UserId = user.Id;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
                return false;

            if (ReferenceEquals(this, obj))
                return true;

            var a = obj as UserDetail;
            if (a == null)
                return false;

            return a.UserId == UserId;
        }

        public override int GetHashCode()
        {
            unchecked
            {
                var hash = 21;

                hash = hash*37 + UserId.GetHashCode();
                
                return hash;
            }
        }
    }

The UserDetail mapping is a little more involved. Identifier is setup as a composite ID. This allows us to use NHibernates mapper to select the column name and the foreign key value. It also imposes the requirement that we have created the Equals() and GetHashCode() overrides.

    public class UserDetailMap : ClassMapping<UserDetail>
    {
        public UserDetailMap()
        {
            Table("UserDetail");

            ComposedId(mapper => mapper.ManyToOne(o => o.ParentUser, x =>
                                                                     {
                                                                         x.Column("UserId");
                                                                         x.ForeignKey("FK_User_Id");
                                                                     }));

            Property(detail => detail.DriversLicense);
            Property(detail => detail.IsDonor);
        }
    }

Persisting The Entities

One common mistake made when using NHibernate to persist related entities is to not set the relevant properties. In this case, the UserDetail.ParentUser property must be set, so that NHibernate can get the value of the ID property. I then to use a setter method to ensure any values are correctly set. In this case, it's the UserDetail.AddUser() method.

The tests file in the example solution gives two examples for persisting the entities to the database. It highlights how to ensure the critical step which happens just after creating the detailToBeSaved object.

        [TestMethod]
        public void SavingAUserWithADetailObject()
        {
            var userToBeSaved = Builder<User>.CreateNew()
                .With(user1 => user1.Id = 0)
                .Build();
            var detailToBeSaved = Builder<UserDetail>.CreateNew().Build();
            // Don't forget the next line...
            userToBeSaved.AddDetail(detailToBeSaved);

            object save;

            using (var txn = session.BeginTransaction())
            {
                save = session.Save(userToBeSaved);
                txn.Commit();
            }

            var loadedUser = session.Get<User>(save);

            loadedUser.ShouldHave().AllPropertiesBut(user => user.Id).EqualTo(userToBeSaved);
            loadedUser.Detail.ShouldHave().AllProperties().EqualTo(detailToBeSaved);

            using (var txn = session.BeginTransaction())
            {
                session.Delete(loadedUser);
                txn.Commit();
            }
        }

A Common Problem

It's pretty common to forget to initialize the child object before persisting. In this case, the UserDetail cannot exist without its parent User. However, if we do not setup the properties on the UserDetail via the AddUser() method or some other means, NHibernate won't know how to associate things. This results in an exception like the following:
Test method Prabu.Tests.OneToOneTests.SavingAUserWithADetailObject threw exception: NHibernate.Exceptions.GenericADOException: could not execute batch command.[SQL: SQL not available] ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'UserId', table 'Prabu.dbo.UserDetail'; column does not allow nulls. INSERT fails. The statement has been terminated.
This happens because NHibernate has no way to figure out what it should be inserting in the UserDetail.UserId field. You can prove this by commenting out the lines of the AddUser() method, and running the test.

Summary

It really is easier and better to just have a surrogate key with which to work. NHibernate is flexible enough to accommodate times when the world isn't perfect. I hope this helped show how to get around one of those sticky situations.

Tuesday, August 7, 2012

FakeItEasy with Action/Action Arguments

Preface

I discovered I couldn't use my go-to mock framework, NSubstitute, when unit testing Silverlight applications. A quick Google scan lead me to FakeItEasy, so I thought I'd give it a try. It's pretty intuitive, and has a decent, fluent interface. Here are some examples from the FakeItEasy Wiki.

A.CallTo(() => foo.Bar()).MustHaveHappened();
A.CallTo(() => foo.Bar()).MustNotHaveHappened();
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.AtLeast.Once);
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.Never);
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.NoMoreThan.Times(4));
A.CallTo(() => foo.Bar()).MustHaveHappened(Repeated.Exactly.Twice);

My Problem

One of the services in the application I've been working on passes a lot of callbacks as parameters. They take the form of Action, Action<T>, Action<T1, T2>, etc. Since I had to be able to test these things, I had to figure a way to invoke the callback in the test. Here's an example of what I was dealing with:

public interface IFoo
{
    void Bar(int number, Action<bool> callback);
}

The Solution

It turns out the solution was pretty simple. FakeItEasy has an extension method (.Invokes()) which can invoke other delegates. This made it possible to extract and invoke the Action callback.

Action Type

When testing something with a simple Action parameter:

public interface IFoo
{
    void Bar(Action callback);
}

FakeItEasy can be used to execute the action. This is done by using the Invokes() extension method. We grab the argument we want, cast it to an Action, then call the action.

var foo = A.Fake<IFoo>();
A.CallTo(() => foo.Bar(A<Action>.Ignored))
               .Invokes(call =>
               {
                   var action = ((Action)call.Arguments.First());
                   action();
               }
         );

Action<T> Type

It's equally easy to handle actions that have one or more parameters. Below is an interface with a method that has two arguments. The Action<bool> callback is the one we want to grab.

public interface IFoo
{
    void Bar(string name, Action<bool> callback);
}

The solution is very close to the previous one. The Invokes() extension method is again used to access the call's arguments. Since the Action<bool> callback is the second argument of the method, the Linq First() expression is dropped in favor of the array. That argument is then cast and called.

var foo = A.Fake<IFoo>();

A.CallTo(() => foo.Bar(A<Action<bool>>.Ignored))
         .Invokes(call =>
         {
             var action = ((Action<bool>)call.Arguments[2]);
             action(true);
         });

Summary

I'm using FakeItEasy more often lately, because it can be used in more project types. Its interface is fluent and intuitive. I hope the example I gave will help others who are starting to check it out.

Thursday, August 2, 2012

Dapper-dot-net, DapperWrapper, and NSubstitute

Preface

Pretty much anyone who knows me will tell you that I'm all about test driven development. It gives you a safety net to refactor code. Unit tests also act as accurate documentation for what tested code does and how it does it. Lately I've been messing with Dapper-dot-net. Since I wanted to use Dapper in one of my recent projects, I had to know how to test its use. This is an example of how to unit test a class encapsulating a database query with Dapper and some other tools.

In this example, I will be using these tools:
Getting Started

The solution contains two projects: the class library and the unit test library. All the dependencies, save one, were added using NuGet. System.Data had to be added manually. The image below shows the solution layout.

Screen shot of the solution highlighting the dependencies.


We'll be querying a database which has a table of orders. The entity which represents an entry in the database is the Order class. This is a simple DTO, made to hold the data stored in the table:

    public class Order
    {
        public int OrderId { get; set; }
        public int CustomerId { get; set; }
        public int ShipperId { get;set; }
    }

The First Test

The first test will check the class is returning the expected data:

    public static class GetOrdersByCustomerIdTests
    {
        public class GetOrdersByCustomerIdContext : ContextSpecification
        {
            protected GetOrdersByCustomerId Sut;
            protected IDbExecutor DbExecutor;

            protected override void Context()
            {
                base.Context();

                DbExecutor = Substitute.For<IDbExecutor>();
                Sut = new GetOrdersByCustomerId();
            }
        }

        [TestClass]
        public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
        {
            private IEnumerable<Order> result;
            private List<Order> expectedResults;

            protected override void Context()
            {
                base.Context();

                expectedResults = Builder<Order>.CreateListOfSize(5)
                    .All().With(order => order.CustomerId = 1)
                    .Build()
                    .ToList();

                DbExecutor.Query<Order>(Arg.Any<string>(), Arg.Any<object>())
                    .Returns(expectedResults);
            }

            protected override void BecauseOf()
            {
                result = Sut.Execute(DbExecutor);
            }

            [TestMethod]
            public void ItShouldReturnTheOrders()
            {
                result.Should().BeEquivalentTo(expectedResults);
            }
        }
    }

There are a few things going on in this test class. DapperWrapper is giving us a means to test the query. Fluent Assertions is giving a nice, readable assertion. NSubstitute is being used to create a mock IDbExecutor. NBuilder is making some test data to be returned by our mock.

To make the test pass, we need to create the following class:

    public class GetOrdersByCustomerId
    {
        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>("", new object()); return query;
        }
    }

Adding the Query to the Test

As you can see, it's pretty simple. The next step is to ensure that the correct query is passed to the database. Since my testing is more BDD, I'm going to modify the Context() method. The Context() method represents the 'Given' of the Given-When-Then set.

 DbExecutor.Query<Order>("select OrderId, CustomerId, ShipperId from Orders where CustomerId=@CustomerId", Arg.Any<object>()).Returns(expectedResults);

This sets the mock to only return the list when the query string matches our expectations. The second parameter, Arg.Any<object>(), sets the mock to match against any object passed into the method.

    public class GetOrdersByCustomerId
    {
        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>("select OrderId, CustomerId, ShipperId from Orders where CustomerId=@CustomerId",                new object());
            
            return query;
        }
    }

Updating the class ensures the test will pass. The query won't really work though, because we're not passing in any parameters. If we were to actually try to use this class, it would throw an exception. So, now we'll start adding parameters to the query.

The First Parameter

With Dapper and DapperWrapper it's possible to simply add the parameter to the Query<T> extension method. The expectation is placed on the mock, and everything works. Here's the test class:

 [TestClass]
 public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
 {
    private IEnumerable<Order> result;
    private List<Order> expectedResults;
    private const int SampleCustomerId = 42;

    protected override void Context()
    {
         base.Context();

         expectedResults = Builder<Order>.CreateListOfSize(5)
            .All().With(order => order.CustomerId = 1)
            .Build()
            .ToList();

         DbExecutor.Query<Order>("select * from Orders where CustomerId=@CustomerId", SampleCustomerId)
            .Returns(expectedResults);
    }

    protected override void BecauseOf()
    {
         Sut.CustomerId = SampleCustomerId;
         result = Sut.Execute(DbExecutor);
    }

    [TestMethod]
    public void ItShouldReturnTheOrders()
    {
         result.Should().BeEquivalentTo(expectedResults);
    }
 }

And the query class:

    public class GetOrdersByCustomerId
    {
        public int CustomerId { get; set; }

        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>("select * from Orders where CustomerId=@CustomerId",
                CustomerId);
         
            return query;
        }
    }

More Than One Parameter

You might notice the second parameter of the Query<T> method is an object. This lets us pass in the parameters using an anonymous object. Pretty spiffy:

    public class GetOrdersByCustomerId
    {
        public int CustomerId { get; set; }
        public int ShipperId { get; set; }

        public IEnumerable<Order> Execute(IDbExecutor connection)
        {
            var query = connection.Query<Order>(
                "select OrderId, CustomerId, ShipperId from Orders where CustomerId=@CustomerId and ShipperId=@ShipperId",
                new { CustomerId, ShipperId });

            return query;
        }
    }

However, the test for the class is not as clean as you might expect. When I first started, I thought the following might work:
    [TestClass]
    public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
    {
        private IEnumerable<Order> result;
        private List<Order> expectedResults;
        private const int SampleCustomerId = 42;
        private const int SampleShipperId = 31;

        protected override void Context()
        {
            base.Context();

            expectedResults = Builder<Order>.CreateListOfSize(5)
                .All().With(order => order.CustomerId = 1)
                .Build()
                .ToList();

            var foo = new { CustomerId = SampleCustomerId, ShipperId = SampleShipperId };
            DbExecutor.Query<Order>("select * from Orders where CustomerId=@CustomerId", foo)
                .Returns(expectedResults);
        }

        protected override void BecauseOf()
        {
            Sut.CustomerId = SampleCustomerId;
            Sut.ShipperId = SampleShipperId;
            result = Sut.Execute(DbExecutor);
        }

        [TestMethod]
        public void ItShouldReturnTheOrders()
        {
            result.Should().BeEquivalentTo(expectedResults);
        }
    }


Unfortunately, this will still fail. NSubstitute fails to match the anonymous type. To get around this, we have to use the Arg.Do<object>() method with a lambda to snag the argument. This argument is assigned to a dynamic type, parameters. A little duck typing allows assertions against the values. The updated test looks like this:


    [TestClass]
    public class WhenThereAreOrdersToReturn : GetOrdersByCustomerIdContext
    {
        private IEnumerable<Order> result;
        private List<Order> expectedResults;
        private const int SampleCustomerId = 42;
        private const int SampleShipperId = 31;
        private dynamic parameters;

        protected override void Context()
        {
            base.Context();

            expectedResults = Builder<Order>.CreateListOfSize(5)
                .All().With(order => order.CustomerId = 1)
                .Build()
                .ToList();

            DbExecutor.Query<Order>("select * from Orders where CustomerId=@CustomerId and ShipperId=@ShipperId",
                                    Arg.Do<object>(o => { parameters = o; }))
                .Returns(expectedResults);
        }

        protected override void BecauseOf()
        {
            Sut.CustomerId = SampleCustomerId;
            Sut.ShipperId = SampleShipperId;
            result = Sut.Execute(DbExecutor);
        }

        [TestMethod]
        public void ItShouldReturnTheOrders()
        {
            result.Should().BeEquivalentTo(expectedResults);
        }

        [TestMethod]
        public void ItShouldUseTheCorrectParameters()
        {
            ((int) parameters.CustomerId).Should().Be(SampleCustomerId);
            ((int) parameters.ShipperId).Should().Be(SampleShipperId);
        }
    }

While the test is correct, it was still failing. It was throwing an RuntimebinderException:

Test method DapperExample.UnitTests.GetOrdersByCustomerIdTests+WhenThereAreOrdersToReturn.ItShouldUseTheCorrectParameters threw exception:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'CustomerId'

It turns out that anonymous types are internal. The test assembly simply didn't have access to the properties of the anonymous type. The solution was pretty simple: expose the internal types to the unit test project. This is done by adding the following line to the AssemblyInfo.cs file:
[assembly: InternalsVisibleTo("DapperExample.UnitTests")]

Epilogue

Dapper is a nifty OR/M with a lot of features. DapperWrapper provides a simple way to do unit tests with projects using Dapper. Using the two, along with a few simple techniques, provides a means of writing good test which will document the code for posterity.