To answer your second question in the first place, no, AOP does not essentially conflict with unit testing. Usually, Id best describes unit test methods and aspects separately.
There are several options in your case.
The easiest way is to simply install the unit test installation method so that the stream has the necessary permissions.
If you do not want to do this, you can distinguish two ways for your unit test. The first is to extract all the code from the methods used for security aspects into separate methods, for example:
[SecurityAspect] void DoSomething() { DoSomethingInternal(); } void DoSomethingInternal() {
You can then run your unit tests against all unprotected internal methods that test the logic in them without worrying about security.
A second approach would be to introduce a mock permission tester into the aspect itself. To be able to do this, you will need to define a separate class and interface that implements the actual security testing logic, something like this (assuming you are passing a stream to check security):
public interface IPermissionsChecker { bool HasPermissions(Thread thread); }
This is your access control for your live system:
public class RealPermissionsChecker : IPermissionsChecker { public bool HasPermissions(Thread thread) {
And this is the one you use in your unit tests
public class MockPermissionsChecker : IPermissionsChecker { public bool HasPermissions(Thread thread) { return true; } }
Now you need to define your aspect as follows:
public class SecurityChecker : OnMethodBoundaryAspect { IPermissionsChecker _checker; public override void OnEntry(MethodExecutionArgs args) { if (!_checker.HasPermissions(Thread.CurrentThread)) throw new SecurityException("No permissions"); } }
The only remaining problem is the need to insert the correct permission check into the aspect.
A little hacky way I did this before is to make the _checker static field and provide a static method to initialize it:
public class SecurityChecker : OnMethodBoundaryAspect { private static IPermissionsChecker _checker; public static void InjectChecker(IPermissionsChecker checker) {
The fact that InjectChecker is static means that you can access it from your application launch (or unit test startup). I suspect that unit test purists will frown on this - and you need to make sure that you call it when the application starts, but I think that this is the easiest way to insert a checker into an aspect, bypass the fact that the rest of your code cannot access instance instances directly.
A more complicated alternative is to override RunTimeInitialize () in your aspect - this method is called by PostSharp when the aspect is initialized. You would probably do something like this:
public override void RuntimeInitialize(MethodBase method) { base.RuntimeInitialize(); this._checker =PermissionsCheckerProvider.Current.GetChecker(); }
You will see that you need to define another class:
public class PermissionsCheckerProvider {
This approach ensures that the method tries to initialize it at the right time, but then you had a problem in that you provided the appropriate current provider before the aspect tried to initialize. Therefore, I personally will probably come up for the first approach, so that everything is simple.
This discusses the issue of dependency injection and RuntimeInitialize. https://codereview.stackexchange.com/questions/20341/inject-dependency-into-postsharp-aspect