繁体   English   中英

NUnit 测试 UserManager、ASP.NET Core 中的 roleManager

[英]NUnit Test UserManager, roleManager in ASP.NET Core

我正在尝试为使用User ManagerRole 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);
        }

以上是行不通的。

  • 我相信这是因为; DevProject 中的 userManager 和 Test Project 中的 userManager 是不同的实例。

我尝试使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM