The easiest way to trick PostSharp attribute properties

I use the PostSharp method attribute for authorization and auditing in my WCF service. It works fine, but now I'm trying to get my unit tests working with an attribute, and I'm struggling to find a way to mock and enter attribute properties.

My attribute is as follows.

[Serializable] [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public class AuthoriseAndAuditAttribute : OnMethodBoundaryAspect { private static ILog logger = AppState.logger; private static Ninject.IKernel _kernel = MyKernel.Kernel; private UserRoleTypesEnum _requiredRole = UserRoleTypesEnum.None; [Inject] public IServiceAuthToken _serviceAuthToken { get; set; } [Inject] public UserSessionDataLayer _userSessionDataLayer { get; set; } public AuthoriseAndAuditAttribute(UserRoleTypesEnum role = UserRoleTypesEnum.None) { _requiredRole = role; _kernel.Inject(this); } public override void OnEntry(MethodExecutionArgs args) { // Get the user session from cookie. UserSession userSession = GetUserSession(); // Check that user is in the required role. bool isAuthorised = (_requiredRole == UserRoleTypesEnum.None || (userSession != null && userSession.Roles.Contains(_requiredRole))); if (!isAuthorised) { logger.Warn("Not authorised for " + args.Method.Name + "."); throw new UnauthorizedAccessException(); } else if (userSession != null) { Thread.CurrentPrincipal = new MyPrincipal(userSession); } } private UserSession GetUserSession() { if (_serviceAuthToken != null) { string sessionID = _serviceAuthToken.GetSessionID(); if (!sessionID.IsNullOrBlank()) { return _userSessionDataLayer.GetForSessionID(sessionID); } } return null; } } 

I have a singleton class that installs the Ninject kernel:

 public class MyKernel { public static StandardKernel Kernel { get; set; } static MyKernel() { Kernel = new StandardKernel(); Kernel.Bind<IServiceAuthToken>().To<ServiceAuthToken>(); Kernel.Bind<UserSessionDataLayer>().To<UserSessionDataLayer>(); } } 

In my WCF service, I use the PostSharp attribute, as shown below:

 [AuthoriseAndAudit(UserRoleTypesEnum.Operator)] public JSONResult<bool> IsAliveAuthorised() { return new JSONResult<bool>() { Success = true, Result = true }; } 

And in my unit test, I use RhinoMocks to try and mock two DI properties in the attribute.

  [TestMethod] public void IsAliveAuthorisedIsAuthorisedTest() { var mockServiceAuthToken = MockRepository.GenerateStrictMock<ServiceAuthToken>(); mockServiceAuthToken.Stub(x => x.GetSessionID()).Return("x"); var mockUserSessionDataLayer = MockRepository.GenerateStrictMock<UserSessionDataLayer>(); mockUserSessionDataLayer.Stub(x => x.GetForSessionID(Arg<string>.Is.Anything)).Return(new UserSession()); MyKernel.Kernel.Bind<ServiceAuthToken>().ToConstant(mockServiceAuthToken); MyKernel.Kernel.Bind<UserSessionDataLayer>().ToConstant(mockUserSessionDataLayer); var service = new MyService(); Assert.IsTrue(service.IsAliveAuthorised().Result); } 

The problem I have is the layout of the objects in the unit test, which will never be set as attribute properties. What am I doing wrong or vice versa, is there a better way to do unit testing of the PostSharp attribute? Also, keeping in mind, I really want to minimize the use of Ninject DI to a minimum minimum.

+7
source share
1 answer

Instead of using the [Inject] attribute in your properties, override them as follows:

  public IServiceAuthToken _serviceAuthToken { get { return _kernel.Get<IServiceAuthToken>(); } } public UserSessionDataLayer _userSessionDataLayer { get { return _kernel.Get<UserSessionDataLayer>(); } } 

In addition, in your test method, you need to re-bind (note also that you used the specific ServiceAuthToken type in the first bind instead of the IServiceAuthToken interface):

 MyKernel.Kernel.Rebind<IServiceAuthToken>().ToConstant(mockServiceAuthToken); MyKernel.Kernel.Rebind<UserSessionDataLayer>().ToConstant(mockUserSessionDataLayer); 
+1
source

All Articles