我想单元测试我的MyUserService,它包含访问Entity Framework Identity UserManager的MyUserRepository。
但是我在模拟UserManager / UserStore时遇到了麻烦。
[TestMethod]
public async Task FindUserByNameAsync_State_Expectation()
{
var data = new List<User>
{
new User { UserName = "AAA" },
}.AsQueryable();
var mockSet = new Mock<DbSet<User>>();
mockSet.As<IDbAsyncEnumerable<User>>()
.Setup(m => m.GetAsyncEnumerator())
.Returns(new TestDbAsyncEnumerator<User>(data.GetEnumerator()));
mockSet.As<IQueryable<User>>()
.Setup(m => m.Provider)
.Returns(new TestDbAsyncQueryProvider<User>(data.Provider));
mockSet.As<IQueryable<User>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<User>>()
.Setup(m => m.GetEnumerator())
.Returns(data.GetEnumerator());
//this obviously doesn't work as userStore doesn't
//have a Users property only UserManager does
var mockUserStore = new Mock<UserStore<User>>()
.Setup(c => c.Users)
.Returns(mockSet.Object);
var repository = new MyUserRepository(mockQueryableUserStore);
var service = new MyUserService(repository);
var user = await service.FindUserByNameAsync("AAA");
Assert.AreEqual("AAA", user.UserName);
}
MyUserService如下所示:
public class MyUserService : IUserService
{
private readonly IUserRepository _repository;
public MyUserService(IUserRepository repository)
{
_repository = repository;
}
public async Task<User> FindUserByNameAsync(string name)
{
var user = await _repository.FindUserByNameAsync(name);
return user;
}
}
和MyUserRepository一样:
public class MyUserRepository : IUserRepository
{
private readonly IUserStore<User> _userStore;
public MyUserRepository(IUserStore<User> userStore)
{
_userStore = userStore;
}
public async Task<User> FindUserByNameAsync(string name)
{
using (var userManager = new UserManager<User>(_userStore))
{
return await userManager.FindByNameAsync(name);
}
}
}
到目前为止,我还没有将UserManager(或其包装器)传递给更喜欢使用IUserStore接口的MyUserRepository构造函数
我唯一的选择是按照this answer将UserManager包装在一个接口中,并使用它来传递给MyUserRepository构造函数?在我看来应该有一个更清洁的方法来做到这一点?