-->

Mocking an IoC Container?

2020-03-30 05:05发布

问题:

Does it make sense to mock an IoC container? If so how would I go about it, using Moq?

I am creating a Prism 4 app, using Unity 2.0 as the IoC container. I inject the container into classes that need its services, rather than using Prism's ServiceLocator. For unit testing, unless I need other Prism services for my test, I simply instantiate the container and register mocks with it. I pass the container to the class under test, which resolves the mocks.

It's all fairly simple, but I am wondering if I should mock the container? Why? If so, how would I do that, if I am using Moq as my mocking framework? Thanks for your help.

回答1:

No, it doesn't make sense to mock a DI container because application classes should not reference a container at all.

Instead of injecting the container into the classes, you should inject only the services that they need. This will also mean that you can unit test them without referencing a DI container at all.



回答2:

I agree with Mark Seemann's answer generally for 99% of classes this works fine.

There are some factory type classes (perhaps classes that take a Model and convert it to a ViewModel where those ViewModels have dependencies) for which this doesn't work. In these cases, I generally accept the interface for the container, rather than its concrete type (IUnityContainer, in your case) and mock as usual.

public class MyWidgetFactory : IMyWidgetFactory
{
     public MyWidgetFactory(IUnityContainer container)
     {
          //...
     }
     public Widget[] GetWidgets()
     {
         //...
     }
}

public class MyWidgetFactoryConsumer
{
     private Widget[] _widgets;
     public MyWidgetFactoryConsumer(IMyWidgetFactory factory)
     {
          _widgets = factory.GetWidgets();
     }
}

Both of the above classes are testable, with the factory class needing to have a mocked version of the IUnityContainer and the consumer needing only the factory itself mocked.