Injecting Typemock Stubs and Mocks using the StructureMap container in a unit test

Someone asked for examples of how you'd inject stubs and mocks when you'd like your object under test to use a container such as StructureMap.

here are a couple of simple tests to show this using Typemock Isolator.

the first uses the string based mocks found in the free community version of Typemock Isolator. the second uses the natural style syntax in the enterprise edition:

  • assume you have ILogger, IEmailer interfaces and a MessageManager class under test that takes both of these in the ctor.
  • The logic under test is: if calling the emailer throws an exception, the logger should be called with the message that was sent

[Test, VerifyMocks]
public void
MessageManager_FailsEmailing_LogsMessage_ReflectiveStructureMap()
{
    StructureMapConfiguration.BuildInstancesOf<IEmailer>().AddConcreteType<Emailer>();
    StructureMapConfiguration.BuildInstancesOf<ILogger>().AddConcreteType<Logger>();

    MockObject<IEmailer> emailStub = MockManager.MockObject<IEmailer>();
    emailStub.AlwaysThrow("Send", new Exception("fake exception"));

    MockObject<ILogger> logMock = MockManager.MockObject<ILogger>();
    logMock.ExpectCall("Write").Args("could not email message abc");

    ObjectFactory.InjectStub(emailStub.MockedInstance);
    ObjectFactory.Inject(logMock.MockedInstance);

    MessageManager mm = ObjectFactory.GetInstance<MessageManager>();
    mm.SendMessage("abc");
}

----------------------------------------

[Test, VerifyMocks]
public void MessageManager_FailsEmailing_LogsMessage_NaturalStructureMap()
{
    StructureMapConfiguration.BuildInstancesOf<IEmailer>().AddConcreteType<Emailer>();
    StructureMapConfiguration.BuildInstancesOf<ILogger>().AddConcreteType<Logger>();

    IEmailer emailStub = RecorderManager.CreateMockedObject<IEmailer>();
    ILogger logMock = RecorderManager.CreateMockedObject<ILogger>();

    using (RecordExpectations re = RecorderManager.StartRecording())
    {
        emailStub.Send("", "", "", "");
        re.Throw(new Exception("fake exception")).RepeatAlways();

        logMock.Write("could not email message abc");
    }

    ObjectFactory.InjectStub(emailStub);
    ObjectFactory.Inject(logMock);

    MessageManager mm = ObjectFactory.GetInstance<MessageManager>();
    mm.SendMessage("abc");
}

Published Thursday, April 24, 2008 7:40 PM by RoyOsherove

Comments

Thursday, April 24, 2008 9:42 PM by Derik Whittaker

# re: Injecting Typemock Stubs and Mocks using the StructureMap container in a unit test

Hey, I have seen this some place not that long ago.... Hum where could that have been.

Thanks for the help.

Friday, April 25, 2008 10:34 AM by Dave

# re: Injecting Typemock Stubs and Mocks using the StructureMap container in a unit test

I don't get it.  

1.  If your subject class is already configured for injection, then why would it need to use the injection framework itself?  Wouldn't it just have its dependencies injected (via constructor or setter)?

2.  If you need to test a class that uses the DI framework, you're better off putting a layer of abstraction between the subject class and your DI framework anyway, in case you want to switch frameworks in the future.  And in that case, you just mock your abstraction layer instead of injecting mocks into the DI config.

Or am I missing something?

Friday, April 25, 2008 11:54 AM by ISerializable - Roy Osherove's Blog

# Pros and Cons and of using an Auto Mocking container in your tests

In regards to my post about injecting mocks and stubs using a container in your tests, Dave asks in the

Friday, April 25, 2008 12:03 PM by .Net World

# Pros and Cons and of using an Auto Mocking container in your tests

In regards to my post about injecting mocks and stubs using a container in your tests, Dave asks in the

Friday, April 25, 2008 12:22 PM by Jeremy

# re: Injecting Typemock Stubs and Mocks using the StructureMap container in a unit test

Roy,

You need to do this:

   ObjectFactory.InjectStub<IEmailer>(emailStub.MockedInstance);

or

ObjectFactory.Inject<ILogger>(logMock.MockedInstance);

You have to inject an object against the desired "PluginType."  By omitting the T in Inject<T>() StructureMap plugs it into "object."