在Moq上使用与UserManager的接口

问题描述 投票:2回答:1

所以,我正在尝试用xunit做一些单元测试,我需要模拟一个接口,它的存储库使用UserManager。我认为这里发生的事情是我在进行单元测试时没有初始化UserManager,因为如果我运行App它可以正常工作。

IUserRepository接口:

public interface IUserRepository : IDisposable
    {
        Task<List<ApplicationUser>> ToListAsync();
        Task<ApplicationUser> FindByIDAsync(string userId);
        Task<ApplicationUser> FindByNameAsync(string userName);
        Task<IList<string>> GetRolesAsync(ApplicationUser user);
        Task AddToRoleAsync(ApplicationUser user, string roleName);
        Task RemoveFromRoleAsync(ApplicationUser user, string roleName);
        Task<bool> AnyAsync(string userId);
        Task AddAsync(ApplicationUser user);
        Task DeleteAsync(string userId);
        void Update(ApplicationUser user);
        Task SaveChangesAsync();
    }

UserRepository:

public class UserRepository : IUserRepository
    {
        private readonly ApplicationDbContext _context;
        private readonly UserManager<ApplicationUser> _userManager;

        public UserRepository(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
        {
            _context = context;
            _userManager = userManager;
        }

        public Task<ApplicationUser> FindByIDAsync(string userId)
        {
            return _context.ApplicationUser.FindAsync(userId);
        }

        public Task<ApplicationUser> FindByNameAsync(string userName)
        {
            return _context.ApplicationUser.SingleOrDefaultAsync(m => m.UserName == userName);
        }

        public Task<List<ApplicationUser>> ToListAsync()
        {
            return _context.ApplicationUser.ToListAsync();
        }

        public Task AddAsync(ApplicationUser user)
        {
            _context.ApplicationUser.AddAsync(user);
            return _context.SaveChangesAsync();
        }

        public void Update(ApplicationUser user)
        {
            _context.Entry(user).State = EntityState.Modified;
        }

        public Task DeleteAsync(string userId)
        {
            ApplicationUser user = _context.ApplicationUser.Find(userId);
            _context.ApplicationUser.Remove(user);
            return _context.SaveChangesAsync();
        }

        public Task<IList<string>> GetRolesAsync(ApplicationUser user)
        {
            return _userManager.GetRolesAsync(user);
        }

        public Task AddToRoleAsync(ApplicationUser user, string roleName)
        {
            _userManager.AddToRoleAsync(user, roleName);
            return _context.SaveChangesAsync();
        }

        public Task RemoveFromRoleAsync(ApplicationUser user, string roleName)
        {
            _userManager.RemoveFromRoleAsync(user, roleName);
            return _context.SaveChangesAsync();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    _context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public Task<bool> AnyAsync(string userId)
        {
            return _context.ApplicationUser.AnyAsync(e => e.Id == userId);
        }

        public Task SaveChangesAsync()
        {
            return _context.SaveChangesAsync();
        }
    }

UserController(只是索引):

public class UserController : CustomBaseController
    {
        private readonly IUserRepository _userRepository;
        private readonly IRoleRepository _roleRepository;

        public UserController(IUserRepository userRepository,IRoleRepository roleRepository)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
        }

        // GET: User
        public async Task<IActionResult> Index()
        {
            List<ApplicationUser> ListaUsers = new List<ApplicationUser>();
            List<DadosIndexViewModel> ListaUsersModel = new List<DadosIndexViewModel>();
            List<Tuple<ApplicationUser, string>> ListaUserComRoles = new List<Tuple<ApplicationUser, string>>();
            var modelView = await base.CreateModel<IndexViewModel>(_userRepository);

            ListaUsers = await _userRepository.ToListAsync();

            foreach(var item in ListaUsers)
            {
                //Por cada User que existir na ListaUsers criar um objecto novo?
                DadosIndexViewModel modelFor = new DadosIndexViewModel();

                //Lista complementar para igualar a modelFor.Roles -> estava a dar null.
                var tempList = new List<string>();

                //Inserir no Objeto novo o user.
                modelFor.Nome = item.Nome;
                modelFor.Email = item.Email;
                modelFor.Id = item.Id;
                modelFor.Telemovel = item.PhoneNumber;

                //Buscar a lista completa de roles por cada user(item).
                var listaRolesByUser = await _userRepository.GetRolesAsync(item);

                //Por cada role que existir na lista comp
                foreach (var item2 in listaRolesByUser)
                    {
                        //Não é preciso isto mas funciona. Array associativo.
                        ListaUserComRoles.Add(new Tuple<ApplicationUser, string>(item, item2));
                        //Adicionar cada role à lista
                        tempList.Add(item2);
                    }
                modelFor.Roles = tempList;
                //Preencher um objeto IndexViewModel e adiciona-lo a uma lista até ter todos os users.
                ListaUsersModel.Add(modelFor);
            }
        //Atribuir a lista de utilizadores à lista do modelo (DadosUsers)
        modelView.DadosUsers = ListaUsersModel;
        //return View(ListaUsersModel);
        return View(modelView);
    }

而测试:

public class UserControllerTest
    {
        [Fact]
        public async Task Index_Test()
        {

            // Arrange
            var mockUserRepo = new Mock<IUserRepository>();
            mockUserRepo.Setup(repo => repo.ToListAsync()).Returns(Task.FromResult(getTestUsers()));
            var mockRoleRepo = new Mock<IRoleRepository>();
            mockRoleRepo.Setup(repo => repo.ToListAsync()).Returns(Task.FromResult(getTestRoles()));

            var controller = new UserController(mockUserRepo.Object, mockRoleRepo.Object);

            controller.ControllerContext = new ControllerContext
            {
                HttpContext = new DefaultHttpContext
                {
                    User = new ClaimsPrincipal(new ClaimsIdentity())
                }
            };
            // Act
            var result = await controller.Index();

            // Assert
            var viewResult = Assert.IsType<ViewResult>(result);
            var model = Assert.IsAssignableFrom<IndexViewModel>(viewResult.ViewData.Model);
            Assert.Equal(2,model.DadosUsers.Count);
        }

        private List<ApplicationUser> getTestUsers()
        {
            var Users = new List<ApplicationUser>();

            Users.Add(new ApplicationUser()
            {
                Nome = "Leonardo",
                UserName = "[email protected]",
                Email = "[email protected]",
                PhoneNumber= "911938567"
            });

            Users.Add(new ApplicationUser()
            {
                Nome = "José",
                UserName = "José@teste.com",
                Email = "José@teste.com",
                PhoneNumber = "993746738"
            });

            return Users;
        }

        private List<IdentityRole> getTestRoles()
        {
            var roles = new List<IdentityRole>();

            roles.Add(new IdentityRole()
            {
                Name = "Admin",
                NormalizedName = "ADMIN"
            });
            roles.Add(new IdentityRole()
            {
                Name = "Guest",
                NormalizedName = "GUEST"
            });

            return roles;
        }
    }

所以问题是:在UserController上我有var listaRolesByUser = await _userRepository.GetRolesAsync(item);,当应用程序工作正常,但是当我运行测试时,GetRolesAsync()方法返回null,或者listaRolesByUser没有初始化。

对不起,如果这看起来有点混乱,我不知道这是否是正确的方法,但这是我到目前为止所学到的。

c# asp.net-mvc entity-framework unit-testing asp.net-identity
1个回答
1
投票

你需要在mock或moq上设置GetRolesAsync(item)方法,只需从它返回null。

所以把它放在模拟用户存储库的声明之下:

mockUserRepo.Setup(repo => repo.GetRolesAsync()).Returns(Task.FromResult(getUsersExpectedRoles()));

这应该确保返回getUsersExpectedRoles()方法的结果而不是null,并且它匹配您要模拟的用户类型。

一般来说,您必须显式声明要在moq对象上设置的方法。因此,测试目标调用的任何方法都需要与之关联的设置。

© www.soinside.com 2019 - 2024. All rights reserved.