[英]asp.net core identity services unable unable to resolve : SignInManager , UserManager , RoleManager
[英]NUnit Test UserManager, roleManager in ASP.NET Core
我正在尝试为使用User Manager和Role Manager 的控制器编写单元测试。
我有操作,涉及创建用户、创建角色以及在角色中添加和删除用户。
我通过控制器构造函数将 usermanager、signInManager 作为依赖项传递。
private readonly IHostingEnvironment hostingEnvironment;
public IHostingEnvironment HostingEnvironment => hostingEnvironment;
public AdminController(IHostingEnvironment environment, SignInManager<IdentityUser> signInManager, ILogger<LoginModel> logger, RoleManager<IdentityRole> roleManager, UserManager<IdentityUser> userManager)
{
_signInManager = signInManager;
_logger = logger;
_roleManager = roleManager;
_userManager = userManager;
hostingEnvironment = environment;
}
我需要测试用户是否已成功添加到角色、从角色中删除等。
我不想测试服务本身,而只想测试操作。
我已按如下方式分离操作以捕获任何异常。
public async Task<bool> AddUserToRole(IdentityUser user, string role)
{
try
{
var addUserToRole = await _userManager.AddToRoleAsync(user, role);
if (addUserToRole.Succeeded)
{
return true;
}
else
{
return false;
}
}
catch(Exception e)
{
throw new Exception("OperationFailed");
}
return false;
}
同样,我解耦了所有涉及 userManager 的操作,并在控制器操作中调用了上述函数。
为了测试,我做了以下工作:
[TestFixture]
public class AdminControllerTest
{
protected TestContext db;
protected Context _db;
protected SignInManager<IdentityUser> signInManager;
protected ILogger<LoginModel> logger;
protected RoleManager<IdentityRole> roleManager;
protected UserManager<IdentityUser> userManager;
protected IHostingEnvironment hostingEnvironment;
[TestCase]
public void Verify_AdminController_Is_Decorated_With_Authorize_Attribute()
{
var userEmail = _db.AspNetUsers.Select(x => x.Email).FirstOrDefault();
var user =await userManager.FindByEmailAsync(userEmail);
var userRole = "Supervisor";
AdminController adminController = new AdminController(hostingEnvironment, signInManager, logger, roleManager, userManager);
var actionResult = adminController.AddUserToRole(user, userRole).Result;
Assert.IsTrue(actionResult);
}
以上是行不通的。
我尝试使用Moq来模拟服务。 但是,如果我模拟服务,则无法将它们传递给控制器实例。
如果我模拟控制器本身,我将无法使用它的动作; 它返回 Null;
我不完全理解嘲笑的概念。
解决上述问题的最佳方法是什么?
我正在使用 ASP.NET Core 2.1 和 NUnit 3.0。
看起来您还没有从AdminController
构造函数中分离出依赖项。
您需要传递抽象/接口,而不是传递实现:
public AdminController(IHostingEnvironment environment,
ISignInManager<IdentityUser> signInManager,
ILogger<LoginModel> logger,
IRoleManager<IdentityRole> roleManager,
IUserManager<IdentityUser> userManager)
请注意,我只添加了I
前缀,但这意味着需要重构您的代码以传递我提到的接口。
现在,我们可以轻松地模拟AdminController
:
[TestFixure]
public class AdminControllerTests
{
private AdminController _adminController;
private IHostingEnvironment _hostingEnvironment = new Mock<IHostingEnvironment>();
private ISignInManager<IdentityUser> _signInManager = new Mock<ISignInManager<IdentityUser>>();
_signInManager
将需要一个设置,该设置使用在您的ISignInManager
中返回 ISignInManager 的方法,假设其名称为Builder()
。
注意:还有其他的模拟方式。 这里有两种方法,或者考虑使用autofac 。
[SetUp]
public void SetUp()
{
_signInManager.Setup(a => a.Builder()).Returns(new[] { new IdentityUser() });
// Do the same for the rest of the dependencies.
//...
_adminController = new AdminController(_hostingEnvironment, _signInManager.Object, ...);
}
现在您可以使用_adminController
实例(请参阅测试方法的正确命名约定):
[Test]
public void Verify_AdminController_Is_Decorated_With_Authorize_Attribute()
{
//...
var actionResult = _adminController.AddUserToRole(user, userRole).Result;
// ...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.