views:

104

answers:

2

We currently have a suite of integration tests that run via MbUnit test suites. We are in the process of refactoring much of the code to use an IOC framework (StructureMap).

I'd like to configure/initialize the container ONCE when the MBUnit test runner fires up, using the same registry code that we use in production.

Is there a way of achieving this in MbUnit?

(EDIT) The version of MbUnit is 2.4.197.

A: 

I understand that you want to spin up only one container for your entire test run and have it be the container used across test suite execution. The MBUnit docs make it look like you might be able to use a TestSuiteFixture and TestSuiteFixtureSetup to accomplish about what you want.

I wanted to speak from the point of view of a StructureMap user and Test Driven Developer.

We rarely use containers in our test suites unless we are explicitly testing pulling things out of the container. When this is necessary I use the an abstract test base class below (warning we use NUnit):

[TestFixture] public abstract class with_container { protected IContainer Container;

[TestFixtureSetUp]
public void beforeAll()
{
    Container = new ServiceBootstraper().GetContainer();
    Container.AssertConfigurationIsValid();
}

} public class Bootstraper { public Bootstraper() { ObjectFactory.Initialize(x => { //register stuff here }); }

public IContainer GetContainer()
{
    return ObjectFactory.Container;
}}

I would recommend for normal tests that you skip the normal container and just use the automocking container included with StructureMap. Here is another handy abstract test base class we use.

 public abstract class Context<T> where T : class
{
    [SetUp]
    public void Setup()
    {
        _services = new RhinoAutoMocker<T>(MockMode.AAA);

        OverrideMocks();

        _cut = _services.ClassUnderTest;

        Given();
    }

    public RhinoAutoMocker<T> _services { get; private set; }
    public T _cut { get; private set; }

    public SERVICE MockFor<SERVICE>() where SERVICE : class
    {
        return _services.Get<SERVICE>();
    }

    public SERVICE Override<SERVICE>(SERVICE with) where SERVICE : class
    {
        _services.Inject(with);

        return with;
    }

    public virtual void Given()
    {
    }

    public virtual void OverrideMocks()
    {
    }
}

and here is a basic test using this context tester:

    [TestFixture]
public class communication_publisher : Context<CommunicationPublisher>
{
    [Test]
    public void should_send_published_message_to_endpoint_retrieved_from_the_factory()
    {
        var message = ObjectMother.ValidOutgoingCommunicationMessage();

        _cut.Publish(message);

        MockFor<IEndpoint>().AssertWasCalled(a => a.Send(message));
    }
}

Sorry if this is not exactly what you wanted. Just these techniques work very well for us and I wanted to share.

KevM
These are integration tests, not unit tests. The container should look exactly like it does in production for our purposes.
Phil Sandler
+1  A: 

Found it. The AssemblyCleanup attribute.

http://www.testingreflections.com/node/view/639

Phil Sandler