0 Comments

One of my current projects is using SpecFlow for testing some complex security logic; there are lots of scenarios so the BDD style of testing is well suited to the problem. I wanted to use the same style of testing for some integration testing where the client is talking to my API but hit a problem of how/where to construct the container as even the client library uses dependency injection to construct itself.

A search quickly found SpecFlow.Autofac by Gaspar Nagy, which provides a plugin to allow AutoFac to be used as a container by SpecFlow. We are using Unity in this project so I used the code at at https://github.com/gasparnagy/SpecFlow.Autofac to create the equivalent project for Unity 4 with the inspiring name of SpecFlow.Unity Smile. I’m not going to explain dependency injection yet again, just a short note on how to use the plugin.

The basic steps to making this work are

  1. Install the NuGet package
  2. Configure the container for the plugin
  3. Adjust the SpecFlow config

Installing the package

First add the package from NuGet into your SpecFlow project

PM> Install-Package SpecFlow.Unity

Configuring the container

Unlike AutoFac, Unity doesn’t have builder methods without going to Unity extensions, and I didn’t want to impose a particular style of construction on consumers of the plugin, so I presume that you already have a way of constructing an appropriate container.

What we do need to do however is make this container available to SpecFlow and also add some additional registrations so that the step definitions are produced by Unity and have their dependencies resolved.  To do this, you need to create a static method in your SpecFlow project and annotate it with a ScenarioDependencies attribute – the plugin has code that will automatically locate this and perform the appropriate configuration in SpecFlow.

A typical method would look something like this…

public static class TestDependencies {

     [ScenarioDependencies]

     public static IUnityContainer CreateContainer()

     {

         // create container with the runtime dependencies

         var container = Dependencies.CreateContainer();

 

         // TODO: add customizations, stubs required for testing

 

         // Registers the build steps, this gives us dependency resolution using the container.

         // NB If you need named parameters into the steps you should override specific registrations

         container.RegisterTypes(typeof(TestDependencies).Assembly.GetTypes().Where(t => Attribute.IsDefined(t, typeof(BindingAttribute))),

                                 WithMappings.FromMatchingInterface,

                                 WithName.Default,

                                 WithLifetime.ContainerControlled);

         return container;

     } }

To register the steps I’ve provided a little extension method in the plugin that does wraps this so instead you can do

container.RegisterStepDefinitions<StepClass>();

One other point is that if you need named dependencies injected into your steps you will have to re-register the step and give the dependencies explicitly. Also you must also have at least one step definition in the same assembly as the ScenarioDependencies method for the it to be found.

SpecFlow Config

The final step is to adjust your SpecFlow config file so that it knows you are using the plugin

    <specFlow>

         <!-- For additional details on SpecFlow configuration options see http://go.specflow.org/doc-config –>

         <unitTestProvider name="NUnit" />

         <runtime stopAtFirstError="false" missingOrPendingStepsOutcome="Inconclusive" />

         <stepAssemblies>

             <stepAssembly assembly="StepAssembly" />

         </stepAssemblies>

         <plugins>

             <add name="SpecFlow.Unity" type="Runtime" />

         </plugins>

     </specFlow>

There’s a full sample project at https://github.com/phatcher/SpecFlow.Unity/tree/master/sample/MyCalculator

Now you have a configured container and steps which are using dependency injection. Finally let me know how you get on at https://github.com/phatcher/SpecFlow.Unity and if there’s any demand for a version for Unity 3.5.

0 Comments

With unit testing one of the precepts is to check one thing in your test, but when you have objects this is difficult to express, since you want to check that the your business process has updated all of the expected properties (positive testing) and also that has not modified things that are not expected to have changed (negative testing).

This becomes even more problematic when you have an object graph, e.g. Order –> OrderLine –> Product where you have to navigate the graph, and reporting accurately where any errors is also a major issue as you need to track property names, collection indexes, etc. etc.

I wrote something to help me a few years ago and due to the nagging nudging of a colleague (I’m looking at you Rob Bagby), I’ve finally reformed it into something that’s hopefully useable by everyone else, called NCheck.

What this allows you to do is compare objects and the library will do a property by property comparison for you, handling collection properties and other referenced entities. What is nice I think, is that you still have control over what properties are included in the comparison and there are helpers for breaking object cycles using the your domain’s concept of identity.

Here’s a short introduction, given a simple class

public class Simple
{
    public int Id { get; set; }

    public string Name { get; set; }

    public double Value { get; set; }
}

we would like to test what happens after running some business service over it, we can do this easily with an NUnit test


[TestFixture]
public class SimpleTest
{
    [Test]
    public void AlgoTest()
    {
        var algo = new ShinyBusinssService();
        var source = new Simple { Id = 1, Name = "A", Value = 1.0 } ;

        var candidate = algo.Run(source);
        Assert.AreEqual(2, candidate.Id, "Id differs");
        Assert.AreEqual("B", candidate.Name, "Name differs");
        Assert.AreEqual(1.2, candidate.Value, "Value differs");
    }
}

If we re-write this using NCheck we get

[TestFixture]
public class SimpleTest
{
    [Test]
    public void AlgoTest()
    {
        var checkerFactory = new CheckerFactory();

        var algo = new ShinyBusinessService();
        var source = new Simple { Id = 1, Name = "A", Value = 1.0 } ;

        var expected = new Simple { Id = 2, Name = "B", Value = 1.2 } ;

        var candidate = algo.Run(source);
        checkerFactory.Check(expected, candidate);
    }
}

Behind the scenes, the CheckFactory class has created a comparison checker (using reflection) to compare each property of the Simple class, but you can also explicitly create a Checker<T> class if you want complete control.

The library is available as a NuGet package and the source code is on GitHub