Asp.net mvc 我可以在ASP.NET MVC控制器基类中测试OnAuthorization的重写吗?

Asp.net mvc 我可以在ASP.NET MVC控制器基类中测试OnAuthorization的重写吗?,asp.net-mvc,controller,master-pages,Asp.net Mvc,Controller,Master Pages,这项工作的机制并不难,但测试它有点奇怪。该场景是,我希望根据基本控制器(IPrincipal对象)的用户属性将一些基本用户数据转储到视图数据中,以便母版页始终拥有它。我需要访问我的IUserManager(一个服务类),它是由控制器工厂中的定制DI提供的。模拟用户对于测试来说没有问题。但是,对于基本控制器中的每个操作,实现这一点的最简单方法是重写OnAuthorization方法。基类如下所示: public abstract class BaseController : Controller

这项工作的机制并不难,但测试它有点奇怪。该场景是,我希望根据基本控制器(IPrincipal对象)的用户属性将一些基本用户数据转储到视图数据中,以便母版页始终拥有它。我需要访问我的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);
    }
}
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
}
问题是我无法在测试中找到启动OnAuth方法的方法。我想在mock UserManager中验证是否调用了SetupUserViewData。我没有使用自定义过滤器,因为我没有一个完整的依赖注入框架(过滤器需要一个IUserManager)


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

您可以通过创建一个类,该类使用调用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);
    }
}
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
}
然后你可以这样测试它:

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);
    }
}
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
}

你认为我在测试正确的东西吗?我想我在这里可能表现得太学术了,但感觉很奇怪,因为我假设控制器在运行时会正确执行,如果有授权用户,就会调用该方法。好吧,如果你要测试我认为你想要的东西,你会测试框架,而不是你的代码。您必须假设您正在使用的框架已经过正确的测试。顺便说一句,您可以通过将控制器强制转换为IAuthorization筛选器并直接调用OnAuthorization()方法来更轻松地测试OnAuthorization()方法本身。(请注意,控制器实现IAuthorizationFilter,此接口将委托给您的重写方法。)@Levi是的,您可以。但在本例中,您仍然需要使用从BaseController继承的控制器(因为它是抽象的)。我更喜欢使用一个专用的测试控制器,然后是一个生产控制器。但在我的示例中,您可以从TestController中删除CallOnAuthorization()方法,并根据需要强制转换TestController。谢谢大家。这是我已经在考虑的解决方案,但我不想通过创造一个先入为主的答案来“毒害”这个问题。谢谢你的验证。很好的电话,李维,演员阵容也不错,我从来没有联系过。