Я использую атрибут метода PostSharp для авторизации и аудита в моей службе WCF. Он работает нормально, но сейчас я пытаюсь заставить мои модульные тесты работать с атрибутом и пытаюсь найти способ смоделировать и внедрить свойства атрибута.
Мой атрибут, как показано ниже.
[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's 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;
}
}
У меня есть одноэлементный класс, устанавливающий ядро Ninject:
public class MyKernel
{
public static StandardKernel Kernel { get; set; }
static MyKernel()
{
Kernel = new StandardKernel();
Kernel.Bind<IServiceAuthToken>().To<ServiceAuthToken>();
Kernel.Bind<UserSessionDataLayer>().To<UserSessionDataLayer>();
}
}
В моей службе WCF я использую атрибут PostSharp, как показано ниже:
[AuthoriseAndAudit(UserRoleTypesEnum.Operator)]
public JSONResult<bool> IsAliveAuthorised()
{
return new JSONResult<bool>() { Success = true, Result = true };
}
И в моем модульном тесте я использую RhinoMocks, чтобы попытаться смоделировать два свойства DI в атрибуте.
[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);
}
Проблема, с которой я столкнулся, заключается в том, что фиктивные объекты в модульном тесте никогда не будут установлены в качестве свойств атрибута. Что я делаю неправильно или, наоборот, есть ли лучший способ провести модульное тестирование атрибута PostSharp? Также, имея в виду, я действительно хочу свести к минимуму использование Ninject DI до минимума.