如何模拟控制器

How to mock the controller

我在控制器中有一个方法可以检查用户的角色以查看应该将用户重定向到哪个页面。 我正在尝试对以下代码进行单元测试

public class HomeController: Controller {

    //...

    public IActionResult Home()
    {
        if (User.IsInRole("Administrators")
        {
            return RedirectToAction("/administrator");
        }
        else
        {
            return RedirectToAction("/user");
        }
    }

    //...other actions
}

模拟设置不正确;您实际上不能模拟具体 类 的成员(除非它们是虚拟的)。但值得庆幸的是,这在这里没什么大不了的,因为您不需要使用模拟。一般来说,以下是处理 HttpContext 测试的工作方式:

    [Test]
    public async Task HomeReturnsNotNull()
    {
        var controller = new HomeController();
        var controllerCtx = new ControllerContext()
        {
            HttpContext = new DefaultHttpContext()
            {
                User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim(ClaimTypes.Role, "Administrators") }))
            }
        };
        controller.ControllerContext = controllerCtx;

        ActionResult index = (ActionResult)controller.Home();

        Assert.IsNotNull(index);
    }

但是依靠自己的一些抽象通常比直接调用 HttpContext 成员更舒服。

冒昧地将'admin'更改为'Administrators',因为我注意到测试中的值与控制器操作中的值之间存在差异。

这样 IsInRole() 检查控制器操作应该正确执行,这在其他测试中应该很有用(因为在这个测试中你似乎只是在检查 null)。