I'd like to discuss with you an idea that came up a while ago while trying to fulfil this need:
As a developer I want to unit test annotations in my actions without having to run the method's body So that I can TDD more effectively and have quicker unit tests. Namely, imagine an action: @SecuredRoles("admin") public String adminStuff(){ ... } It would be interesting to have a way to test the @SecuredRoles without having to run the method's body. Upon discussion within the TDD group, a nice solution was suggested (in italic. Skip below for my comments regarding Struts) : So I would test and implement each aspect in isolation of the other - the authorization would be implemented as a decorator (a-la GoF decorator pattern) adding authorization to the underlaying (decorated) MVC app. BTW I got to this technique by TDDing the separate aspects (this is a good example of where the tests drive the design). The technique to getting there is quite simple: 1. Extract an interface from your main class with all the public methods 2. Implement a decorator which adds authorization rules to a decorated underlaying object. The decorator can implement the authorization rules using your annotations (see this is where the academic meets the practical - you'll in fact be reusing the already existing interceptor but adapting it to a test-driven architecture) 3. in your tests, test the decorator providing a mock underlaying decorated object, asserting in each test that given a request with a user that has certain roles the underlaying method should or should not be called. The code might end up like this (semi-pseudo code but you get the idea) Tests: test_admin_can_call_method_a() { // setup a fake request with admin role: httpRequest = buildRequestWithRole("admin"); // setup a mock app decorated with an authorzation decorator: MockApp app = new MockApp(); AuthorizationDecorator authorizer = new AuthorizationDecorator(app); // act - try calling method A in the decorator: authorizer.MethodA(httpRequest); // assert - underlaying method a should have been called: Assert(app.MethodA.WasCalled==true); } test_regularUser_cannot_call_method_a() { // setup a fake request with regular user role: httpRequest = buildRequestWithRole("regular user"); // setup a mock app decorated with an authorzation decorator: MockApp app = new MockApp(); AuthorizationDecorator authorizer = new AuthorizationDecorator(app); // act - try calling method A in the decorator: authorizer.MethodA(httpRequest); // assert - underlaying method a should not have been called: Assert(app.MethodA.WasCalled==false); } In the SUT: interface IApp { void MethodA() void MethodB() ... } // this is the real app implementing methodA, methodB etc class RealApp : IApp { void MethodA() void MethodB() ... } // this is responsible for authorization class AuthorizingDecorator : IApp { private IApp _decorated; public AuthorizationDecorator(IApp decorated) { _decorated = decorated; } // each method is implemented using annotations // and calling the underlaying decorated object @SecuredRoles("admin, manager") public void MethodA() { _decorated.MethodA(); } @SecuredRoles("regular user") public void MethodB() { _decorated.MethodB(); } } Then in your final MVC application you'd wire up the decorator with the RealApp object: IApp app = new AuthorizingDecorator(new RealApp()); This design is incompatible with Struts2 - if you decorate DecoratedAction with OriginalAction, all Struts-related things (e.g. ParamsInterceptor populating Action's fields from request, and I assume every other interceptor's behaviour as well) will no work on DecoratedAction, because it doesn't extend OriginalAction but rather delegates to OriginalAction. E.g, a "someRequestParam" would be populated OriginalAction if it was in the request, but it won't populate originalAction.someRequestParam in DecoratedAction. It would be very interesting to support the Decorator Pattern in Struts actions. What are your thoughts on it? Miguel Almeida