Sonntag, 24. Januar 2016

Fluently testing your Autofac configuration

Given the popularity of the Autofac IoC container, we were surprised that there seemed to be no public library that supported testing your Autofac configuration.



Well now there is FluentAssertions.Aufofac which supports test the DI configuration like this

    container.Should().Have().Registered<SuperCoolService>()
        .AsSelf()
        .As<ICoolService>()
        .Singleton();

    container.Should().Have().Registered(superCoolInstance);

    container.Should().Have().Registered<OtherCoolService>()
                .Named<ICoolService<("prettyCool");

    container.Should().Have().NotRegistered<UncoolService>("uncool");

And not even registration but also resolving which asserts that you did not forget any dependency

    container.Should().Resolve<ICoolService>().As<SuperCoolService>()
        .AutoActivate();

But maybe there is just no need to test Dependency Injection? Let's see...

Why test your IoC configuration in the first place?


In general, the more you apply Dependency Injection (DI) the easier becomes unit testing and Test-driven Development (TDD).

This is because the complexity of constructing all dependencies is shifted to the so called Composition Root, i.e. the place where you "wire up" and configure all your dependencies.
Undoubtedly, the best way to do this is by using some Inversion of Control (IoC) container.

With an application growing in complexity, there is also growing need to organize and test the IoC configuration.

Here is the usual story: During release sprints we typically develop features in parallel that form complete workflows (think epics or themes, if you will). While carving these out, we mock out dependencies to the other features. This way everyone can move forward without needing the other features completed.

For example, you're designing the coolest recommendation view on the planet. While your buddy is on the recommendation service on the backend, you will register a mock, i.e.

    ...
    builder.RegisterType<MockRecommendations>().As<IGetRecommendations>();
    // builder.RegisterType<RecommendationService>().As<IGetRecommendations>();
    ...

Once your buddy gives thumbs up for integration testing you switch to the real thing. Finally, you finish and move on to the next feature.

So far, so good. But then, a critical issue with your view (or likewise viewmodel, controller) rises in production. No problem, you go for the hotfix, switch back to your mock so you can better and quicker reproduce the problem. You fix the problem but then, you forget to switch back from the mock to the productive recommendation service - which gives you a serious #facepalm.


Wouldn't it be nice if there was a test saving you from breaking the release next time? Well, now there is.

Fluent interfaces and readable code


Most of the time, we prefer using this stack
There is nothing special about this choice. But there is at least one thing these libraries have in common: They all share a profound intent on improving accessibility and readability by providing a fluent API.

In the rare case that you - as a developer - never quoted that "Code is read much more often than it is written" and are wondering why you should thrive for readable code in the first place, then here is a hand-picked selection of classic references that we found to be helpful
Learn to Read the Source

Keine Kommentare:

Kommentar veröffentlichen