Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I access the full power of Autofac in UnitTests, using the Moq integration

My project (which happens built on top of Orchard, though I don't think that's relevant) uses Autofac. I am writing unit tests in which I want to stub out any dependencies using Moq, and I'm using the Autofac/Moq integration to achieve this.

This is fine for any simple dependencies that are being passed in as constructor arguments. (Autofac documentation provides details of how to achieve this here).

But because I don't ever have a containerBuilder, I don't see how to use a lot of Autofac's power - lamda registration, registering generics, marking properties to be auto-wired. etc.

  • Am I wrong and it is accessible somehow?
  • Is this stuff just not available due to some inherent constraint of the scenario?
  • Is it possible, just not implemented in this Autofac/Moq integration (yet)?
  • Is there a good work around?
like image 559
Brondahl Avatar asked Feb 23 '15 19:02

Brondahl


People also ask

What is mock behavior strict?

When creating a mock, we can also give it strict or loose behavior. Strict behavior means that exceptions will be thrown if anything that was not set up on our interface is called. Loose behavior, on the other hand, does not throw exceptions in situations like this. Mocks, by default, are loose.

What is MOQ Testing C#?

Moq is a mocking framework for C#/. NET. It is used in unit testing to isolate your class under test from its dependencies and ensure that the proper methods on the dependent objects are being called.


1 Answers

Some of the features, you've mentioned, can be used with AutoMock class and some won't make sense any more. With AutoMock we do not deal with ContainerBuilder class - this is for simplicity, we don't want to have to code all those registering instructions, but to only register the ones interesting for us. So from creation of AutoMock object with GetLoose or GetStrict method we deal only with built IContainer object ready to resolve things. Fortunately for us IContainer still allows us to extend its registration set, however Autofac won't support that with its convenient extension methods as they are built to work with ContainerBuilder object. This is perfectly reasonable because for Autofac perspective extending definitions on IContainer object is something uncommon. ContainerBuilder is supposed to handle registration and IContainer is supposed to handle resolving.

Here I will, as an example, present how with AutoMock we may use auto-wired properties functionality:

using (var mock = AutoMock.GetLoose())
{
    mock.Container.ComponentRegistry.Register(
        RegistrationBuilder
            .ForType<MyClass>()
            .PropertiesAutowired()
            .CreateRegistration<MyClass, ConcreteReflectionActivatorData, SingleRegistrationStyle>()
    );
}

As you see now we have to deal with all the ugliness of autofac internal code which normally is hidden by extension methods. PropertiesAutowired functionality may be easily used with AutoMock, however lamda registration will not make much sense any more. What lambda registration gives us is that object being registered in ContainerBuilder can depend on other registered object which will be resolved during building ContainerBuilder to IContainer so we do not need to care for the order of the registering instructions. Here we already have ready made IContainer and it won't be built again so such deffering of registration is pointless. If we want to pass to some registered object another already registered object then we may simply resolve it first and then use it.

So as summary:

  • autofac features are generally accessible with AutoMock
  • some of the features are not available due to constraints of not registering things in ContainerBuilder but in IContainer object instead. Other stuff is probably not implemented yet and maybe will be delivered in future.
  • for almost all cases there are good workarounds as shown in the example above
like image 198
mr100 Avatar answered Oct 18 '22 03:10

mr100