因此,我正在尝试使用xunit进行单元测试,并且需要模拟一个接口,其中它的存储库使用UserManager。 我认为这里发生的情况是,在进行单元测试时未初始化UserManager,因为如果运行应用程序,则可以正常工作。
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();
}
}
用户控制器(仅限索引):
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 = "leonardo@teste.com",
Email = "leonardo@teste.com",
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
没有被初始化。抱歉如果这看起来有点混乱,我不知道这是否是正确的做法,但这是我迄今为止学到的。
GetRolesAsync(item)
应返回用户(item)的角色。我没有展示那个getTestRoles()
方法,我的错误。getTestRoles()
是一个包含示例角色的List
。我会添加它的。我正在仓储中使用UserManager
从用户(item)返回用户角色。 - Leonardo HenriquesGetRolesAsync(It.IsAny<ApplicationUser>())
并创建一个新的方法来为用户创建角色。谢谢。 - Leonardo Henriques