ASP.NET MVC单元测试自定义AuthorizeAttribute

11
我正在处理一个ASP.NET MVC 4项目(.NET框架4),想知道如何正确地对自定义AuthorizeAttribute进行单元测试(我使用NUnit和Moq)。
我重写了两个方法:AuthorizeCore(HttpContextBase httpContext)HandleUnauthorizedRequest(AuthorizationContext filterContext)。正如你所看到的,这些方法分别需要HttpContextBaseAuthorizationContext参数,但我不知道如何对它们进行模拟。
目前为止就做到这里了:
[Test]
public void HandleUnauthorizedRequest_UnexistingMaster_RedirectsToCommonNoMaster()
{
    // Arrange
    var httpContext = new Mock<HttpContextBase>();
    var winIdentity = new Mock<IIdentity>();
    winIdentity.Setup(i => i.IsAuthenticated).Returns(() => true);
    winIdentity.Setup(i => i.Name).Returns(() => "WHEEEE");
    httpContext.SetupGet(c => c.User).Returns(() => new ImdPrincipal(winIdentity.Object)); // This is my implementation of IIdentity
    var requestBase = new Mock<HttpRequestBase>();
    var headers = new NameValueCollection
        {
           {"Special-Header-Name", "false"}
        };
    requestBase.Setup(x => x.Headers).Returns(headers);
    requestBase.Setup(x => x.HttpMethod).Returns("GET");
    requestBase.Setup(x => x.Url).Returns(new Uri("http://localhost/"));
    requestBase.Setup(x => x.RawUrl).Returns("~/Maintenance/UnExistingMaster");
    requestBase.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(() => "~/Maintenance/UnExistingMaster");
    requestBase.Setup(x => x.IsAuthenticated).Returns(() => true);
    httpContext.Setup(x => x.Request).Returns(requestBase.Object);
    var controller = new Mock<ControllerBase>();
    var actionDescriptor = new Mock<ActionDescriptor>();
    var controllerContext = new ControllerContext(httpContext.Object, new RouteData(), controller.Object);

    // Act
    var masterAttr = new ImdMasterAuthorizeAttribute();
    var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object);
    masterAttr.OnAuthorization(filterContext);

    // Assert
    Assert.AreEqual("", filterContext.HttpContext.Response);
}

在这一行代码中:masterAttr.OnAuthorization(filterContext);,抛出了一个NullReferenceException异常。我猜测这与我们尚未模拟的上下文中的值有关。

非常感谢您的任何帮助。

提前致谢。

真诚地, Yanik Ceulemans

1个回答

8

没有属性代码,人们只能猜测。但是,要开始调查,您可以使用MockBehavior.Strict创建模拟对象。这样,当在模拟对象上调用方法或属性时,如果之前没有进行设置,则Moq将抛出异常。该异常将带有方法/属性的名称:

var httpContext = new Mock<HttpContextBase>(MockBehavior.Strict);

3
原来我在 HttpContext 上缺少了 Items 属性。插入以下代码:var dictionary = new Dictionary<string, object>(); httpContext.Setup(c => c.Items).Returns(dictionary); 解决了我的问题。谢谢! - Yanik Ceulemans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接