Reputation: 1199
I'm quite new to unit testing and I struggle one thing. I want to create WebAPI in ASP.NET MVC with test project containing test methods for the controllers. I've read quite a lot about IoC/DI and I've already used it in other projects, but not with unit testing. As one of many advatages of IoC/DI is often mentioned mock classes injection for test methods, but I've never find a way how to do it using separate projects.
So how do I set the IoC/DI container so it contains both production and mock classes, but of course the mock classes are not interfearing with the production code and are separately located and only visible in the test project?
Upvotes: 0
Views: 378
Reputation: 8725
First I completely agree with @NightOwl888, you should not use IoC
containers in UT
, however I've seen some projects where the IoC
is coupled with the system code, In those cases it is easy to inject the dependency using the IoC
container.
In unit testing you first simulate the conditions for the behavior you want to verify, then execute the unit and then verify the behavior(AAA Pattern).
When you use IoC
conteiners you usally do it with the RRR Pattern which fits together with the AAA
pattern.
So how do I set the IoC/DI container so it contains both production and mock classes?
It's a little bit depends on the IoC
container you use, but in the bottom line the concept is same:
In the Arrange
section:
You resolve the class under test(now the CUT
has your fakes as a dependencies...)
Usually you should release objects in the TearDown
...
Each IoC
container allows you to do it in a different way; Autofac
use the last registration, Castle Windsor
has IsDefualt
method(there are more way to do it castle..) and so on...
Upvotes: 1
Reputation: 56869
Short answer, you don't.
Each application should have its own composition root. Since unit tests are placed in a separate project and run under a separate process from your WebApi project, they are separate applications. Thus, they will have separate DI configurations. So in a nutshell 1 executable process == 1 composition root.
DI is a pattern. It does not require a DI container. Therefore, neither your WebApi project nor your unit test project require a DI container.
Although some people prefer to use a DI container during unit testing, to me it seems like overkill. Unit testing is about testing 1 class under test at a time. The rest of the classes in the test scenario should all be stubs or mocks. If following good design practices (not using constructor over-injection), you will typically have no more than 4 instances in a scenario - the class under test and up to 3 fake classes. Using the new
keyword to create these instances is not only simpler, it makes the unit tests easier to understand. And one important aspect of unit tests is to make them easy to understand so other people can easily see what is being tested and how so they can be used to understand the API when the documentation is not clear.
During integration testing or user acceptance testing, you may consider using DI more seriously to compose the components together because in those situations you typically have more than one class under test to compose together.
Upvotes: 5