Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test this IoC Registration using Named components? (Autofac)

I'm looking at converting some of our complex creation code to use an IoC container, Autofac, and because I'm a great believer in TDD, I'm writing unit tests for the Module configuration.

Most of the functionality is very easy to test e.g.

var obj = container.Resolve<IThing>();
Assert.IsInstanceOfType(obj, typeof(ThingImplementer));

But we have a number of cases where we have multiple implementers of the same interface and different implementers are being passed to different concrete classes. I've resolved this by using named registration e.g.

builder.RegisterType<ThingImplementer>().Named<IThing>("Implementer1");
builder.RegisterType<OtherImplementer>().Named<IThing>("Implementer2");
builder.Register(c => new Foo(c.ResolveNamed<IThing>("Implementer1"))).As<IFoo>();

What I can't figure out is an easy way to write a unit test for ensuring that Foo gets ThingImplementer and not OtherImplementer. I'm wondering if it is worth the effort, we do have high level integration tests that cover this, but they don't give the documentation or refactoring benefits that unit tests do.

Would you write a unit test for this? If so, how?

like image 760
Andy Lowry Avatar asked Nov 28 '10 14:11

Andy Lowry


2 Answers

You would typically not test the configuration of your container in your unit tests. In your unit test environment you don't use a container to inject any dependencies (you do this by hand) and if you would do this, you would inject fake objects, and not the real/production types. Therefore the container configuration is typically unknown to your unit tests.

What I tend to do sometimes is test whether the container is able to create the application's root types (such as the controller classes of a MVC application, or the Page classes of an WebForms application). Because the container will instantiate a graph of objects, it will give me a good idea whether the container is configured correctly. However, I'm never interested if the container returns the correct implementation. Most of the time there is even only one implementation of a registered interface that is accessible for the application root, so it hardly could go wrong.

If you want to test your container configuration, perhaps it is too complex and you should try to simplify your application design so you can simplify the registration.

like image 176
Steven Avatar answered Nov 12 '22 02:11

Steven


Nothing new here, just extensions of Steven's points.

As Steven says, that's definitely not a Unit Test. You could perhaps view it as a learning test. Have a look at the Ninject test suite - it shows how they do such tests (but remember they're writing a Container). I assume autofac has similar tests.

Having said that, if you feel there's interesting behavior and it wont become flaky, it's not harm to stick it into an integration suite.

The other point regarding the fact that it's external is also very valid - see the notion of an Onion Architecture

like image 2
Ruben Bartelink Avatar answered Nov 12 '22 04:11

Ruben Bartelink