【发布时间】:2012-01-19 04:18:54
【问题描述】:
我正在使用 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 的使用。
【问题讨论】:
-
那么属性分配了什么?实际的对象,还是它们为空?
-
不,它们不为空。 _kernel.Inject(this) 调用设置两个属性对象。我试图用我的单元测试做的是改变 ninject 内核用来设置它们的对象,这就是不工作的位。
-
对,所以您希望 Mock 对象存在,但“真实”对象仍在显示?
-
是的,就是这样,虽然我是“希望”而不是“期待”:)。
-
Ninject 是您项目的关键部分还是仅用于单元测试目的?
标签: wcf unit-testing ninject rhino-mocks postsharp