在 ASP.NET Core 中模拟 IPrincipal [英] Mocking IPrincipal in ASP.NET Core
问题描述
我有一个 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屋!