.net - 如何对使用 Controller.User 变量的 Controller 操作进行单元测试?

标签 .net asp.net-mvc unit-testing

我有一个 Controller 操作,如果用户已经登录( User.Identity.IsAuthenticated ),它会自动重定向到新页面。为此场景编写单元测试以确保重定向发生的最佳方法是什么?

最佳答案

我一直在使用以下带有 Moq 的 Mock 来允许在我的单元测试中设置各种条件。首先,HttpContextBase 模拟:

    public static Mock<HttpContextBase> GetHttpContextMock(bool isLoggedIn)
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();
        var principal = AuthenticationAndAuthorization.GetPrincipleMock(isLoggedIn);

        context.SetupGet(c => c.Request).Returns(request.Object);
        context.SetupGet(c => c.Response).Returns(response.Object);
        context.SetupGet(c => c.Session).Returns(session.Object);
        context.SetupGet(c => c.Server).Returns(server.Object);
        context.SetupGet(c => c.User).Returns(principal.Object);

        return context;
    }

每个可能提供有用 Mock 的属性都在这里设置。这样,如果我需要添加类似推荐人的内容,我可以使用:
Mock.Get(controller.Request).Setup(s => s.UrlReferrer).Returns(new Uri("http://blah.com/");

“GetPrincipleMock”方法用于设置用户。它看起来像这样:
    public static Mock<IPrincipal> GetPrincipleMock(bool isLoggedIn)
    {
        var mock = new Mock<IPrincipal>();

        mock.SetupGet(i => i.Identity).Returns(GetIdentityMock(isLoggedIn).Object);
        mock.Setup(i => i.IsInRole(It.IsAny<string>())).Returns(false);

        return mock;
    }

    public static Mock<IIdentity> GetIdentityMock(bool isLoggedIn)
    {
        var mock = new Mock<IIdentity>();

        mock.SetupGet(i => i.AuthenticationType).Returns(isLoggedIn ? "Mock Identity" : null);
        mock.SetupGet(i => i.IsAuthenticated).Returns(isLoggedIn);
        mock.SetupGet(i => i.Name).Returns(isLoggedIn ? "testuser" : null);

        return mock;
    }

现在,我在测试中的 Controller 设置如下所示:
var controller = new ProductController();
var httpContext = GetHttpContextMock(true); //logged in, set to false to not be logged in

ControllerContext controllerContext = new ControllerContext(httpContext.Object, new RouteData(), controller);
controller.ControllerContext = controllerContext;

这是一个有点冗长的设置,但是一旦您准备好一切,测试各种条件就会变得容易得多。

关于.net - 如何对使用 Controller.User 变量的 Controller 操作进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1783612/

相关文章:

css - Bootstrap 3 : placing a link beside a dropdown control

Python 2.4 - 单元测试 : TypeError: run() takes exactly 2 arguments (1 given)

c# - 在浏览器中编辑文档 (.doc)

c# - 在运行时更新 app.config system.net 设置

c# - 如何在 C# 中比较字符串和枚举

c# - 使用 Func<T, string> 委托(delegate)列表对 IQueryable 执行 .Select()

javascript - 行政部分设计决策

asp.net - 无法加载文件或程序集 'System.Runtime.Serialization.Primitives' 或其依赖项之一

unit-testing - 默认情况下,单元测试和集成测试使用相同的名称

ruby - 是否有等同于 RSpec 的 before( :all) in MiniTest?