【问题标题】:Can I test the override for OnAuthorization in an ASP.NET MVC controller base class?我可以在 ASP.NET MVC 控制器基类中测试 OnAuthorization 的覆盖吗?
【发布时间】:2010-02-17 15:50:29
【问题描述】:

完成这项工作的机制并不难,但测试它有点奇怪。场景是我想基于基本控制器(一个 IPrincipal 对象)的 User 属性将一些基本用户数据转储到视图数据中,以便母版页始终拥有它。我需要访问我的 IUserManager(一个服务类),它由控制器工厂中的自定义 DI 提供。模拟用户对于测试来说是没有问题的。但是,为基本控制器中的每个操作实现此目的的最简单方法是通过覆盖 OnAuthorization 方法来实现。基类如下所示:

public abstract class BaseController : Controller
{
    public BaseController(IUserManager userManager)
    {
        UserManager = userManager;
    }

    public IUserManager UserManager { get; private set; }

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        UserManager.SetupUserViewData(User, ViewData);
    }
}

问题是我无法在测试中找到触发 OnAuth 方法的方法。我想在我的模拟 UserManager 中验证 SetupUserViewData 是否被调用。我没有使用自定义过滤器,因为我没有成熟的依赖注入框架(过滤器需要获取 IUserManager)。

有什么建议吗?由于这将在任何地方使用,我想正确进行测试。

【问题讨论】:

    标签: asp.net-mvc controller master-pages


    【解决方案1】:

    您可以通过使用调用 OnAuthorization 方法的公共方法创建从基本控制器继承的类来实现此目的。像这样的:

    public class TestController : BaseController {
        public TestController(IUserManager userManager) : base(userManager) {
        }
    
        public void CallOnAuthorization(AuthorizationContext filterContext) {
            OnAuthorization(filterContext);
        }
    }
    

    然后你像这样测试它:

    [Test]
    public void TestMethod() {
        var userManager = //Mock usermanager;
        var filterContext = //Mock AuthorizationContext;
        var controller = new TestController(userManager);
        controller.CallOnAuthorization(filterContext);
        //Assert here
    }
    

    【讨论】:

    • 你认为我测试的东西是对的吗?我想我在这里可能表现得过于学术,但感觉很奇怪,因为我假设控制器将在运行时正确执行并在有授权用户的情况下调用该方法。
    • 好吧,如果你要测试我认为你想要的东西,你会测试框架,而不是你的代码。您必须假设您使用的框架已经过适当的测试。
    • BTW - 您可以通过将控制器转换为 IAuthorizationFilter 并直接调用 OnAuthorization() 方法来更轻松地测试 OnAuthorization() 方法本身。 (请注意,Controller 实现了 IAuthorizationFilter,并且此接口委托给您重写的方法。)
    • @Levi 是的,你可以。但是在这个例子中你仍然需要使用一个继承自 BaseController 的控制器(因为它是抽象的)。而且我更喜欢使用专用的测试控制器,然后是生产控制器之一。但是您可以在我的示例中从 TestController 中删除 CallOnAuthorization() 方法,并根据需要强制转换 testcontroller。
    • 谢谢,伙计们。这是我已经在考虑的解决方案,但我不想通过创建一个先入为主的答案来“毒化”这个问题。感谢您的验证。很好的电话,列维,我也在演员阵容中,我从来没有建立联系。
    猜你喜欢
    • 1970-01-01
    • 2018-11-04
    • 2021-11-14
    • 1970-01-01
    • 2021-09-21
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    相关资源
    最近更新 更多