views:

107

answers:

1

I'm trying to use SUT Factory 'pattern' to create my SUT.

Given the SUT structure:

namespace MySut
{
    public class Dep1
    {
    }

    public class Dep2
    {
    }

    public class Sut
    {
        public Sut( Dep1 dep1, Dep2 dep2 )
        {
        }
    }
}

I'm using AutoFixture, and am wondering what's the best way to collapse the following Specifications and associated SUT factory method [valuable but]busywork:

namespace MySpecifications
{
    using MySut;
    public class MySpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = CreateSut();
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = CreateSut( new Mock<Dep1>().Object );
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = CreateSut( new Mock<Dep2>().Object );
        }

        private object CreateSut( )
        {
            return CreateSut( CreateDep1(), CreateDep2() );
        }

        private object CreateSut( Dep1 dep1 )
        {
            return CreateSut( dep1, CreateDep2() );
        }

        private object CreateSut( Dep2 dep2 )
        {
            return CreateSut( CreateDep1(), dep2 );
        }

        private Sut CreateSut( Dep1 dep1, Dep2 dep2 )
        {
            return new Sut( dep1, dep2 );
        }

        private static Dep1 CreateDep1()
        {
            return new Fixture().CreateAnonymous<Dep1>();
        }

        private static Dep2 CreateDep2()
        {
            return new Fixture().CreateAnonymous<Dep2>();
        }
    }
}

to something like:

    public class MyAutoFixturedSpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = CreateSut();
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = CreateSut( new Mock<Dep1>().Object );
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = CreateSut( new Mock<Dep2>().Object );
        }

        private object CreateSut( params object[] injectedNonAnonymouses )
        {
            return new Fixture(  ).Build<Sut>(  )./*??????*/;
        }
    }

or:

    public class MyAnticipatedAutoFixturedSpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = new Fixture(  ).Build<Sut>().CreateAnonymous(  );
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = new Fixture().Build<Sut>()/*.With( new Mock<Dep1>().Object )*/.CreateAnonymous();
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = new Fixture().Build<Sut>()/*.With( new Mock<Dep2>().Object )*/.CreateAnonymous();
        }
    }

i.e., removing all the factory junk, so that my specifications can easily cope with a transition to:

namespace MySutWithNewDependency
{
    public class Dep1
    {
    }

    public class Dep2
    {
    }

    public class Dep3
    {
    }

    public class Sut
    {
        public Sut( Dep1 dep1, Dep2 dep2, Dep3 dep3 )
        {
        }
    }
}

While there is overlap with the notion of an automocking container, I'm still not looking for a golden hammer - just a way to be able to mock 0 or 1 thing at a time and yet be able to customise creation of dependent objects without having to revisit explicit calls to the Sut constructor whenever its' set of dependencies changes.

(Also using xUnit.net (SubSpec style), Moq, Ninject2 (though dont want to use DI in my specifications))

+2  A: 

AutoFixture can more or less do all of this for you without all that extra scaffolding. I'd start out with a basic Fixture and use it to resolve Sut:

var fixture = new Fixture();
var sut = fixture.CreateAnonymous<Sut>();

This assumes that Dep1 and Dep2 can be created automatically by AutoFixture, but as presented, they can because they have default constructors.

When you want to override a specific type, you can use the Register method like this:

var fixture = new Fixture();

var mock = new Mock<Dep1>();
fixture.Register(mock.Object);
// Setup mock if necessary...

var sut = fixture.CreateAnonymous<Sut>();

This will cause fixture to use mock.Object any time Dep1 is needed, including when the Sut constructor is invoked. This definitely fits your requirement of being robust in the face of evolving constructors, and one of the main reasons AutoFixture was built like that.

In a more realistic scenario, Dep1 and Dep2 might be interfaces, in which case you might want to Register them as part of a 'default Fixture'. This is certainly also possibly because that last call to Register wins. This means that you can configure a Fixture instance with some good defaults and still be able to override specific types whenever you need to do this.

I personally use AutoFixture as an auto-mocking container. This discussion provides a hint at how this would be possible with the AutoFixture 1.1 API, but the new kernel for AutoFixture 2.0 will provide much better extensibility options. When I get to it, I will write a blog post on this subject.

P.S. Sorry about the late reply, but I didn't see your question before now. In the future, feel free to ping me (e.g. on Twitter) for a faster reply.

Mark Seemann
Thanks, Mark. I'd considered @ing you in a comment on the question as a way of pinging, but thanks for the offer! I believe I got most of the stuff you covered in the answer (your blog posts are v clear - but thanks for solidifying my understanding) I did see `Register` but assumed that the fluent builder would allow me to do it inline (and not have the registration persist and potentially 'randomly' influence subsequent `fixture` usages, a la a magic base class or using your normal DI registrations in the context of your tests. I have a two month old tip download so maybe its already there.
Ruben Bartelink
BTW thanks for the frictionless TDD. Many of the normally unwritten conventions you have in there are very useful - might be useful to do a master post that indexes them and gives them one sentence snappy summary each. Other question - are you seriously not going to put a Ninject chapter in your DI book but have a Spring.NET one? I know V2 is underdocumented, but surely that's where you come in :P (I'm a dead tree person so I still have a long wait ahead, though I'm guessing an EAP access would be a very good idea for me rather than discovering DI do's and dont's organically over time)
Ruben Bartelink
Looking at the discussion, it sounds like (or I'm choosing to hope/assume it does) you'll be building both a fluent and long-lived syntax for doing both a `Register` and `Resolve` style hook which should fit this usage pattern.
Ruben Bartelink
You can pretty much view Fixture as a test-specific, convention-based DI Container. All the Register methods end up invoking the Customize method, so that's where all the persistent magic happens. While the Fluent API is nice I still find that the less you use it, and the more you can rely on basic conventions, the more maintainable your tests will be. In any case, once you invoke the Build method, you 'leave' the Fixture, so nothing will be persisted in that case.
Mark Seemann
Concerning the Zero-Friction TDD posts, did you see this index? http://blog.ploeh.dk/2009/01/28/ZeroFrictionTDD.aspx
Mark Seemann