Possible Duplicate:
Using IoC for Unit Testing
I think I do have a Problem understanding the way Unit Tests and/or Dependency Injection are working. I'm using NUnit and Rhino Mocks for Unit testing and Ninject as an Dependency Incection Framework. In general, I though those two would fit perfeclty - but somehow, it seems like it gets just more complicated and harder to understand.
(I'll try to make up a good example, to keep it clean and easy. It's about me, riding a bike).
1.) Without DI / Unit Tests:
Without knowing of DI and Unit Tests, my code would have looked like that - and I'd be happy:
public class Person
{
public void Travel()
{
Bike bike = new Bike();
bike.Ride();
}
}
public class Bike
{
public void Ride()
{
Console.WriteLine("Riding a Bike");
}
}
To ride my bike i would just need: new Person().Travel();
2.) With DI:
I don't want that tight coupling, so I need an Interface and a NinjectModule! I'd have some Overhead, but that will be fine, as long as the code is easy to read and understand. I'll just pass the code for the modified Person class, the Bike class is unchanged:
public class Person
{
IKernel kernel = new StandardKernel(new TransportationModule());
public void Travel()
{
ITransportation transportation = kernel.Get<ITransportation>();
transportation.Ride();
}
}
I could still ride my bike with just: new Person().Travel();
3.) Considering Unit-Testing (without DI):
To be able to check if the Ride-Method is called properly, I'll need a Mock. As far as I know, there are gernerally two ways to inject an Interface: Constructor Injection and Setter Injection. I choose Constructor Injection for my example:
public class Person
{
ITransportation transportation;
public person(ITransportation transportation)
{
this.transportation = transportation;
}
public void Travel()
{
transportation.Ride();
}
}
This time, i would neet to pass the bike: new Person(new Bike()).Travel();
4.) With DI and preparing for Unit-Tests
The class in 3. Considering Unit-Testing (without DI) would do the job without modification, but I would need to call new Person(kernel.Get<ITransportation>());
. Through that, it feels like I'm loosing the benefit from DI - the Person class could call Travel without any coupling and any need to know what kind of class the transportation is. Also, I think this form is lacking a lot of the readability of example 2.
Is this how it is done? Or are there other - more elegant ways achieving Dependency Injection and the possibility to unit test (and mock)?
(Looking back, it seems the example is really bad - everyone should know what kind of transportation device he is riding at the moment...)