Asp .Net核心单元测试模拟UserManager.CreateAsync并返回身份结果 [英] Asp .Net Core Unit Test Mock UserManager.CreateAsync and return Identity Result

查看:299
本文介绍了Asp .Net核心单元测试模拟UserManager.CreateAsync并返回身份结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

致力于.Net Core Project并创建了以下服务,以在页面之间共享常用方法.

Working on .Net Core Project and created below service to share common methods across the pages.

namespace MyApp.Tests.Services
{
    public class UserServiceTest
    {
        [Fact]
        public async Task CreateUser_ShouldCreateUser()
        {
            var user = new UserResponse
            {
                Id = "111",
                Email = "john@email.com",
                FirstName = "John",
                LastName = "Doe",
                CompanyName = "SomeCompany",
                PhoneNumber = "9123456789"
            };

            var appUser = new ApplicationUser
            {
                UserName = user.Email,
                Email = user.Email,
                FirstName = user.FirstName,
                LastName = user.LastName,
                CompanyName = user.CompanyName,
                PhoneNumber = user.PhoneNumber
            };

            var logger = Mock.Of<ILogger<UserService>>();
            var mockUserStore = new Mock<IUserStore<ApplicationUser>>();
            mockUserStore
                .Setup(x => x.CreateAsync(appUser, CancellationToken.None))
                .ReturnsAsync(IdentityResult.Success).Verifiable();

            // Tried this one as well but still getting null instead of IdentityResult
            // mockUserStore
            //     .Setup(x => x.CreateAsync(appUser, CancellationToken.None))
            //     .ReturnsAsync(new IdentityResultMock(true));

            var userManager = new UserManager<ApplicationUser>(mockUserStore.Object, null, null, null, null, null, null, null, null);
            var _userService = new UserService(userManager, logger);

            var result = await _userService.CreateUserInApp(user);

            Assert.True(result.Succeeded);
        }
    }

    public class IdentityResultMock : IdentityResult
    {
        public IdentityResultMock(bool succeeded) {
            base.Succeeded = succeeded;
         }
    }
}

还为该服务编写了单元测试用例,如下所示,以测试UserService

Also wrote the Unit Test case for this service like below to test the UserService

namespace MyApp.Tests.Services
{
    public class UserServiceTest
    {
        [Fact]
        public async Task CreateUser_ShouldCreateUser()
        {
            var user = new UserResponse
            {
                Id = "111",
                Email = "john@email.com",
                FirstName = "John",
                LastName = "Doe",
                CompanyName = "SomeCompany",
                PhoneNumber = "9123456789"
            };

            var appUser = new ApplicationUser
            {
                UserName = user.Email,
                Email = user.Email,
                FirstName = user.FirstName,
                LastName = user.LastName,
                CompanyName = user.CompanyName,
                PhoneNumber = user.PhoneNumber
            };

            var logger = Mock.Of<ILogger<UserService>>();
            var mockUserStore = new Mock<IUserStore<ApplicationUser>>();
            mockUserStore
                .Setup(x => x.CreateAsync(appUser, CancellationToken.None))
                .ReturnsAsync(IdentityResult.Success).Verifiable(); ;

            var userManager = new UserManager<ApplicationUser>(mockUserStore.Object, null, null, null, null, null, null, null, null);
            var _userService = new UserService(userManager, logger);

            var result = await _userService.CreateUserInApp(user);

            Assert.True(result.Succeeded);
        }
    }
}

在用户服务中运行测试

var createResult = await _userManager.CreateAsync(appUser);

createResult由于此测试用例失败,并且获取空引用异常,我获取了空值. 如果我可以从模拟CreateAsync设置中返回IdentityResult,那么它将通过但不确定我在做什么错. 也无法创建IdentityResult的对象,因为'Succeeded'受保护并且不能显式分配值. 请帮忙.谢谢:)

createResult I am getting null due to this Test Case is failing and getting null reference exception. If I could return IdentityResult from mock CreateAsync setup then it will pass but not sure what wrong I am doing. Also Can not create object of IdentityResult because 'Succeeded' is protected and can not assign value explicitly. Please help. Thanks :)

推荐答案

我们需要查看构造函数内部发生的情况:

We need to see what is happening inside the constructor:

var userManager = new UserManager<ApplicationUser>(mockUserStore.Object, null, null, null, null, null, null, null, null);

但不是真的.如果要在此处测试UserService,那么应该嘲笑的是UserManager,而不是内部依赖项IUserStore.

But not really. If you are testing the UserService here, then what you should be mocking is the UserManager and not it's internal dependency IUserStore.

那是为什么?因为UserManager的内部可能会更改,然后您必须同时更改UserManager测试和UserService测试.

Why is that? Becaus the internals of the UserManager might change and then you'll have to change both the UserManager tests and the UserService tests.

像对待IUserStore一样模拟UserManager的创建,您会发现它是UserStore或其他完全不在单元测试范围内的其他依赖项.

Mock the create of the UserManager as you do for the IUserStore and you'll see it was some other dependency in UserStore or somewhere totally outside the scope of the unit test.

编辑1

我想我已经解决了您的问题:

I think I figured out your problem:

mockUserStore
    .Setup(x => x.CreateAsync(appUser, CancellationToken.None))
    .ReturnsAsync(IdentityResult.Success).Verifiable();

然后通过

var result = await _userService.CreateUserInApp(user);

用户对象和appUser对象不同,因此模拟框架不会返回期望值.

User object and appUser object are not the same, so the mocking framework does not return the expected value.

为确保这是问题所在,请尝试使用

To make sure that this is the problem, try to mock with

mockUserStore
    .Setup(x => x.CreateAsync(It.IsAny<ApplicationUser>(), It.IsAny<CancellationToken>()))
    .ReturnsAsync(IdentityResult.Success).Verifiable();

这篇关于Asp .Net核心单元测试模拟UserManager.CreateAsync并返回身份结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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