Dependency Injection (DI) and Inversion of Control (IOC) with PostSharp for Testing
6 posts • Page 1 of 1
Dependency Injection (DI) and Inversion of Control (IOC) with PostSharp for Testing
SITUATION:
In the context of a Test Driven Development (TDD), you often need to inject (replace) a real, production-object, with a fake one for testing.
Suppose you are testing a Coffee Maker GUI Application, that lets user to turn on a coffee maker machine, and check it's status.
For testing you want to replace the actual coffee maker controller with a mock (stub, emulator, fake) controller.
There are several techniques to accomplish this, most common ones are:
- DI through constructor - the dependant object is passed via constructor argument;
- DI through setter - setter is exposed for setting the object;
- DI through factory method (my proffered) - a dependent object is instantiated by a (protected virtual in C#) factory method, that is overridden to return a fake object for testing.
All of these methods have some drawbacks.
QUESTION:
Can we employ PostSharp to ease this problem and make DI less intrusive?
POSSIBLE SOLUTIONS:
1. My first suggestion would be to use CodeWeaver to replace code that instantiate dependent objects (e.g. 'this.coffeeMaker = new CoffeeMakerController();') with test code that returns an instance of TestCoffeMakerControllerMock instead.
What's the easiest way to accomplish said?
2. (bad solution) Use OnMethodBoundary aspect to intercept invocation to either CoffeeMakerController constructor or factory method in the tested method. This method has a disadvantage of enforcing use of an aspect on the production class - precisely the thing I am trying to solve.
Any ideas are welcome.
Regards,
Roman
------------------------------------------------------------------------[/quote][/quote][/quote]
Start with absurd, and work you way backward.
Roman V. Gavrilov
- rgavrilov
- Posts: 5
- Joined: Sat Jan 12, 2008 4:55 pm
- Full Name: Roman V. Gavrilov
Re: Dependency Injection (DI) and Inversion of Control (IOC) with PostSharp for Testing
I had a vision this morning (while shaving, to be precise).
There should be a custom attribute ReplaceAttribute, which would look like this:
[Replace(typeof(CustomerProcessFactory)]
public class InsteadOfCustomerProcessFactory
{
static CustomerProcess CreateCustomerProcess()
{
// Do something special, for instance logging.
return CustomerProcess.CreateCustomer();
}
}
[Replace(typeof(CustomerProcess))]
public class InsteadOfCustomerProcess
{
static public string Behavior;
static Customer CreateCustomer( CustomerProcess @this, string firstName, string lastName )
{
if ( Behavior == "dataException" )
throw new DataException("The database is not available (fake).");
else
@this.CreateCustomer( firstName, lastName );
}
}
Then there would be a transformation applied to the whole application (not to individual assemblies, but really to the whole application). The transformation would detect the [Replace] attribute and would replace all calls to the replaced methods:
- instead-of methods should have the same name and signature as the replaced method
- instead-of methods should be static. if they replace instance methods, the first parameter should be of the type of the 'replaced' class.
- instead-of classes should not define all methods of the replaced type. Non-replaced methods are simply... not replaced.
- to avoid recursions, calls would not be replaced in "instead-of" methods.
In order to perform application-level transformations, a new command-line utility could be used (based on the PostSharp Host infrastructure).
It's not trivial (two weeks for a working prototype?), since we cannot rely on Laos.
Seems inspiring?
Gael
There should be a custom attribute ReplaceAttribute, which would look like this:
[Replace(typeof(CustomerProcessFactory)]
public class InsteadOfCustomerProcessFactory
{
static CustomerProcess CreateCustomerProcess()
{
// Do something special, for instance logging.
return CustomerProcess.CreateCustomer();
}
}
[Replace(typeof(CustomerProcess))]
public class InsteadOfCustomerProcess
{
static public string Behavior;
static Customer CreateCustomer( CustomerProcess @this, string firstName, string lastName )
{
if ( Behavior == "dataException" )
throw new DataException("The database is not available (fake).");
else
@this.CreateCustomer( firstName, lastName );
}
}
Then there would be a transformation applied to the whole application (not to individual assemblies, but really to the whole application). The transformation would detect the [Replace] attribute and would replace all calls to the replaced methods:
- instead-of methods should have the same name and signature as the replaced method
- instead-of methods should be static. if they replace instance methods, the first parameter should be of the type of the 'replaced' class.
- instead-of classes should not define all methods of the replaced type. Non-replaced methods are simply... not replaced.
- to avoid recursions, calls would not be replaced in "instead-of" methods.
In order to perform application-level transformations, a new command-line utility could be used (based on the PostSharp Host infrastructure).
It's not trivial (two weeks for a working prototype?), since we cannot rely on Laos.
Seems inspiring?
Gael
Gael Fraiteur, project leader
got good support? consider donating to the project.
got good support? consider donating to the project.
- gfraiteur
- Site Admin
- Posts: 674
- Joined: Tue Dec 18, 2007 3:09 pm
- Full Name: Gael Fraiteur
- Company: postsharp.org
Re: Dependency Injection (DI) and Inversion of Control (IOC) with PostSharp for Testing
Anything new about this topic? Im wondering because the vision of Gael would help me a lot with my vision of NMock2 with support for mocking of classes.
Happy coding
Urs
Urs Enzler
- ursenzler
- Posts: 2
- Joined: Sat Jan 12, 2008 4:55 pm
- Full Name: Urs Enzler
Re: Dependency Injection (DI) and Inversion of Control (IOC) wit
There will be some support for dependency injection in next version of PostSharp. I'll be discuting it also with the Microsoft Enterprise Library team to make sure PostSharp can interact with their upcoming application block providing lightweight depencency injection.
Gael
Gael
Gael Fraiteur, project leader
got good support? consider donating to the project.
got good support? consider donating to the project.
- gfraiteur
- Site Admin
- Posts: 674
- Joined: Tue Dec 18, 2007 3:09 pm
- Full Name: Gael Fraiteur
- Company: postsharp.org
Re: Dependency Injection (DI) and Inversion of Control (IOC) wit
Gael Fraiteur, project leader
got good support? consider donating to the project.
got good support? consider donating to the project.
- gfraiteur
- Site Admin
- Posts: 674
- Joined: Tue Dec 18, 2007 3:09 pm
- Full Name: Gael Fraiteur
- Company: postsharp.org
6 posts • Page 1 of 1