Execute unit tests against DB and keep it unchanged using AOP
Few weeks ago, I wrote about how to extend Nunit to support RollBack attribute and how to execute unit tests against database and keep it unchanged.
Today, I’ve tried to achieve the same functionality but using AOP. Actually, I’ll use PostSharp platform in order to weave needed code in each test method decoreted with RollBackAttribute. PostSharp does it at compile time and do nothing in the run-time. Many people like to have an option to change the aspect during run-time but in my case I do not need it and PostSharp is ideal for doing what I need.
Let me start with RollBackAttribute class. It inherited from OnMethodBoundaryAspect and override OnEntry and OnExit methods. It begins a new transaction per each call and it rollbacks it after execution.
[sourcecode language="csharp"]
[Serializable]
public class RollBackAttribute : OnMethodBoundaryAspect
{
ITransaction transation = null;
public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
transation = SessionManager.CurrentSession.BeginTransaction();
}
public override void OnExit(MethodExecutionEventArgs eventArgs)
{
if (transation != null)
{
transation.Rollback();
transation.Dispose();
}
}
}
[/sourcecode]
Now we are ready to decorate any test method with RollBack attribute.
[sourcecode language="csharp"]
[Test]
[RollBack]
public void AddNewModule()
{
Module module = CreateModule();
ModuleRepository repository = new ModuleRepository(SessionManager.CurrentSession);
repository.Add(module);
Module result = RetrieveModelFromatabase(module, SessionManager.CurrentSession);
Assert.IsNotNull(result);
}
[/sourcecode]
But how it will look after compilation? Below is a screen shot from .Net Reflector.
In red is the code we have in AddNewModule test method and in light blue is the execution of OnEntry and OnExit methods of OnMethodBoundaryAspect. As you can see the code we needed is weaved into the method during compile time and will be executed.

Leave a Reply