你可能在错误的层次上进行测试,但这个测试是有意义的。我的意思是,如果我使用“authorize(Roles =“Superhero”)"属性标记一个方法,如果已经标记了它,我就不需要测试。我(认为)想要测试的是未经授权的用户无法访问,而经授权的用户可以访问。
对于未经授权的用户,可以进行以下测试:
var user = SetupUser(isAuthenticated, roles);
var controller = SetupController(user);
SomeHelper.Invoke(controller => controller.MyAction());
Assert.AreEqual(401,
controller.ControllerContext.HttpContext.Response.StatusCode, "Status Code");
虽然不容易,我花了10个小时才做出来。但是这里它就是了。我希望有人可以从中受益或者说服我去做别的事情 :) (顺便提一下 - 我正在使用Rhino Mock)
[Test]
public void AuthenticatedNotIsUserRole_Should_RedirectToLogin()
{
var mocks = new MockRepository();
var controller = new FriendsController();
var httpContext = FakeHttpContext(mocks, true);
controller.ControllerContext = new ControllerContext
{
Controller = controller,
RequestContext = new RequestContext(httpContext, new RouteData())
};
httpContext.User.Expect(u => u.IsInRole("User")).Return(false);
mocks.ReplayAll();
var result =
controller.ActionInvoker.InvokeAction(controller.ControllerContext, "Index");
var statusCode = httpContext.Response.StatusCode;
Assert.IsTrue(result, "Invoker Result");
Assert.AreEqual(401, statusCode, "Status Code");
mocks.VerifyAll();
}
虽然没有这个辅助函数,那也不是很有用:
public static HttpContextBase FakeHttpContext(MockRepository mocks, bool isAuthenticated)
{
var context = mocks.StrictMock<HttpContextBase>();
var request = mocks.StrictMock<HttpRequestBase>();
var response = mocks.StrictMock<HttpResponseBase>();
var session = mocks.StrictMock<HttpSessionStateBase>();
var server = mocks.StrictMock<HttpServerUtilityBase>();
var cachePolicy = mocks.Stub<HttpCachePolicyBase>();
var user = mocks.StrictMock<IPrincipal>();
var identity = mocks.StrictMock<IIdentity>();
var itemDictionary = new Dictionary<object, object>();
identity.Expect(id => id.IsAuthenticated).Return(isAuthenticated);
user.Expect(u => u.Identity).Return(identity).Repeat.Any();
context.Expect(c => c.User).PropertyBehavior();
context.User = user;
context.Expect(ctx => ctx.Items).Return(itemDictionary).Repeat.Any();
context.Expect(ctx => ctx.Request).Return(request).Repeat.Any();
context.Expect(ctx => ctx.Response).Return(response).Repeat.Any();
context.Expect(ctx => ctx.Session).Return(session).Repeat.Any();
context.Expect(ctx => ctx.Server).Return(server).Repeat.Any();
response.Expect(r => r.Cache).Return(cachePolicy).Repeat.Any();
response.Expect(r => r.StatusCode).PropertyBehavior();
return context;
}
因此你可以确认未分配角色的用户没有访问权限。我试图编写一个测试以证明相反的情况,但是在深入挖掘MVC管道两个小时后,我将其留给手动测试人员。(当我到达VirtualPathProviderViewEngine类时放弃。WTF?我不想与VirtualPath或Provider或ViewEngine打交道,更不想处理它们三者的联合!)
我很好奇为什么在这个声称“可测试”的框架中这么难。