我有一个 ASP.NET MVC Core 应用程序,我正在为其编写单元测试。其中一种操作方法使用用户名来实现某些功能:
SettingsViewModel svm = _context.MySettings(User.Identity.Name);
这显然在单元测试中失败了。我环顾四周,所有建议都来自 .NET 4.5 到模拟 HttpContext。我相信有更好的方法可以做到这一点。我试图注入(inject) IPrincipal,但它抛出了一个错误;我什至尝试过这个(我想是出于绝望):
public IActionResult Index(IPrincipal principal = null) {
IPrincipal user = principal ?? User;
SettingsViewModel svm = _context.MySettings(user.Identity.Name);
return View(svm);
}
但这也引发了错误。 在文档中也找不到任何内容...
最佳答案
Controller 的 User
is accessed通过HttpContext
of the controller .后者is stored在 ControllerContext
内.
设置用户的最简单方法是为构造的用户分配不同的 HttpContext。我们可以使用 DefaultHttpContext
为此,我们不必模拟所有内容。然后我们只需在 Controller 上下文中使用 HttpContext 并将其传递给 Controller 实例:
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
将正常工作(如果您在代码中使用它来确定用户是否已通过身份验证)。
关于c# - 在 ASP.NET Core 中模拟 IPrincipal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38557942/