2

I don't think this was asked before, although it's really hard to search for a term like unit test ioc container and not find a question about how to implement IoC in order to perform unit tests.

I would like to have unit tests against the IoC container itself basically because sometimes I have issues with the container (like you could with any other part of an application), and it's pretty troublesome to test the resolution of dependencies merely debugging.

If I could introduce unit tests for these cases, I think it would save me a lot of trouble.

Update

Is something like this, not an Unit Test? Is it an integration test?

[TestClass]
public class IoC
{
    private IWindsorContainer _container;

    [TestInitialize]
    public void TestInit()
    {
        _container = new WindsorContainer();
        _container.Install(new WindsorInstaller());
    }

    [TestMethod]
    public void ContainerShouldResolve_MembershipProvider()
    {
        ContainerShouldResolve<IMembershipProvider>();
    }

    public void ContainerShouldResolve<T>()
    {
        T result = _container.Resolve<T>();
        Assert.IsInstanceOfType(result, typeof(T));
    }
}

The only real "not self-contained" reference is a connection string I had to wire into app.config. Also: when trying to resolve PerWebRequest lifestyle components I had to add the related httpModule, too.

By the way: by doing this I found out the source of my issue in little time compared to what it was taking me to debug it through using the web application.

bevacqua
  • 47,502
  • 56
  • 171
  • 285
  • Do you mean: integration testing to make sure all components are wired up together correctly? – Tomasz Nurkiewicz Apr 21 '12 at 15:50
  • Not exactly. I want to set up a test where I configure the container, throw an abstract type (or interface) at it, and have it correctly resolve to an expected type. – bevacqua Apr 21 '12 at 15:53
  • 1
    related: http://stackoverflow.com/questions/9896344/ioc-container-check-for-errors-at-compile-time – Steven Apr 21 '12 at 16:01
  • Also take a look at this wiki page: http://simpleinjector.codeplex.com/wikipage?title=How-to&referringTitle=Documentation#Verifying_Configuration. Although it is written for the Simple Injector container, the advice is valid for all containers. – Steven Apr 21 '12 at 16:06
  • btw, do you want to test the correctness of the DI framework, or your DI configuration for a certain DI framework? As jimmi said, don't test the container itself. However, it is very valid to test the correctness of your own DI configuration. – Steven Apr 21 '12 at 16:14
  • No. I want to test the correctness of my configuration. Asserting the configuration I provided has the ability to resolve types as expected. – bevacqua Apr 21 '12 at 16:24

2 Answers2

1

This falls more into integration testing category. Your components registration might do all kinds of external systems calls (database, file system, network, services ...) when resolved, and this is where unit testing ends.

One approach you can do to this kind of (integration) testing, is to simply resolve your application root type. This might not be complete (especially when your application does large bits of lazy loading), but is often good enough to spot missing bits.

Edit #2 (in response to OP edit)

Of course, it might be possible to do root-resolve test without actually touching any external systems mentioned, but there still might be lot of dependencies wiring and setting up going on real objects (as in, not fakes/stubs). This is many potential reasons to fail (I'd say even too many for unit test) and is up to developer to judge what testing category this falls into.

Doing component-resolve test (resolve that relates to much smaller scope) might be fine for unit test, but once again - it's for developer to judge and it largely depends on what the objects do upon resolve. Most modern containers usually offer more than simple storage and this should be taken into account.

What I'm trying to say is, if you have say DaoModule and you want to verify it can be resolved from container, sure, this might be an unit test. But if resolving your DaoModule setups connection and queries DB to see if it is in valid state, you probably need to reconsider where such test would go.

Edit #1 (in response to OP comment under question)

I want to set up a test where I configure the container, throw an abstract type (or interface) at it, and have it correctly resolve to an expected type.

Basically, you want to verify whether your container works? Don't do that. Simply pick a container that is tested and you can assume it can do its job. If you feel the need to unit test your 3rd party components, you really should be choosing different ones.

k.m
  • 30,794
  • 10
  • 62
  • 86
  • 1
    Although component wiring does perhaps fall more in the 'integration' category, it will normally be easy to write an unit test for the configuration (thus something that runs in isolation), since testing the configuration can be done by checking whether the container can resolve all root objects, and since constructor and property injection should only be used for construction -and those constructors should not do anything else than store those dependencies- constructing an object graph should *not* do any web service or database calls and resolving an instance can run in isolation. – Steven Apr 21 '12 at 16:11
  • So is testing the container like this wrong? Why? (see my update) – bevacqua Apr 21 '12 at 16:35
  • @Nico: it would be wrong to do register-resolve test. They way you do it is fine, it just IMO it falls into integration tests category. I don't know what your app's root object does, but it might potentially do *lot of* stuff - I've edited my answer slightly. – k.m Apr 21 '12 at 17:08
  • @Steven: while I agree it unit testing *is possible* in such cases, categorization often depends on what objects do/how they were registered. There might be (but on the other hand there might be not) lot of stuff happening that is beyond your control to make it proper unit test. I'd say it's a judgement call and will vary from app to app. – k.m Apr 21 '12 at 17:10
  • @jimmy, on edit #1: What I wanted is to check if things such as naming conventions for resolving types are working properly, not test the framework (Castle in my case) itself. – bevacqua Apr 21 '12 at 17:16
  • Thanks for helping me differentiate between unit and integration testing. I see your point, and it's a very valid one. – bevacqua Apr 21 '12 at 17:18
0

If you really whant to write unittests for infrastructure-code like IoC to check that the IoC implementation is correct you can look into the unittests sourcecode of the IoC.

For example DotNet-s autofac IoC Unittests

The other answers and comments on your question (and I in the first run also) thought that you want to write an autoamted test that makes shure that your components where correctly wired by the IoC. Most of us call this kind of test an integrationtest and not a unittest.

k3b
  • 14,517
  • 7
  • 53
  • 85