在 ASP.NET Core 中模拟 IPrincipal [英] Mocking IPrincipal in ASP.NET Core

查看:37
本文介绍了在 ASP.NET Core 中模拟 IPrincipal的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ASP.NET MVC Core 应用程序,我正在为其编写单元测试.一种操作方法使用用户名来实现某些功能:

I have an ASP.NET MVC Core application that I am writing unit tests for. One of the action methods uses User name for some functionality:

SettingsViewModel svm = _context.MySettings(User.Identity.Name);

在单元测试中显然失败了.我环顾四周,所有建议都来自 .NET 4.5 来模拟 HttpContext.我相信有更好的方法来做到这一点.我试图注入 IPrincipal,但它抛出了一个错误;我什至尝试过这个(我想是出于绝望):

which obviously fails in the unit test. I looked around and all suggestions are from .NET 4.5 to mock HttpContext. I am sure there is a better way to do that. I tried to inject IPrincipal, but it threw an error; and I even tried this (out of desperation, I suppose):

public IActionResult Index(IPrincipal principal = null) {
    IPrincipal user = principal ?? User;
    SettingsViewModel svm = _context.MySettings(user.Identity.Name);
    return View(svm);
}

但这也引发了错误.在文档中也找不到任何内容...

but this threw an error as well. Couldn't find anything in the docs either...

推荐答案

控制器的 User 通过HttpContext 控制器.后者存储ControllerContext.

The controller’s User is accessed through the HttpContext of the controller. The latter is stored within the ControllerContext.

设置用户的最简单方法是为构造的用户分配不同的 HttpContext.我们可以使用 DefaultHttpContext 为此目的,这样我们就不必模拟一切.然后我们只需在控制器上下文中使用该 HttpContext 并将其传递给控制器​​实例:

The easiest way to set the user is by assigning a different HttpContext with a constructed user. We can use DefaultHttpContext for this purpose, that way we don’t have to mock everything. Then we just use that HttpContext within a controller context and pass that to the controller instance:

var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
{
    new Claim(ClaimTypes.Name, "example name"),
    new Claim(ClaimTypes.NameIdentifier, "1"),
    new Claim("custom-claim", "example claim value"),
}, "mock"));

var controller = new SomeController(dependencies…);
controller.ControllerContext = new ControllerContext()
{
    HttpContext = new DefaultHttpContext() { User = user }
};

创建自己的ClaimsIdentity,确保传递明确的authenticationType 到构造函数.这确保 IsAuthenticated 将正常工作(以防您在代码中使用它来确定用户是否已通过身份验证).

When creating your own ClaimsIdentity, make sure to pass an explicit authenticationType to the constructor. This makes sure that IsAuthenticated will work correctly (in case you use that in your code to determine whether a user is authenticated).

这篇关于在 ASP.NET Core 中模拟 IPrincipal的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆