【发布时间】:2019-10-06 07:34:00
【问题描述】:
在我的 ASP.Net 应用程序中,我有一个要进行单元测试的控制器。以下是一些相关代码:
public class UserController : Controller
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IUserRepository _userRepository;
public UserController(IUserRepository repo, UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
{
_userRepository = repo;
_userManager = userManager;
_signInManager = signInManager;
}
public async Task<IActionResult> Index()
{
return View(await _userRepository.GetAll().ToListAsync());
}
我想测试 Index() 方法,所以我使用 https://github.com/romantitov/MockQueryable 创建了一个 DummyDbContext 来帮助模拟存储库。
相关代码:
public class DummyDbContext
{
private ICollection<User> _users;
public Mock<DbSet<User>> _dbsetUsers
{
get
{
return _users.AsQueryable().BuildMockDbSet();
}
}
public DummyDbContext()
{
_users= new List<User>();
_users.Add(new User("Alan"));
_users.Add(new User("Claire"));
_users.Add(new User("Paul"));
_users.Add(new User("John"));
}
在我的测试课中,我进行如下操作:
public class UserControllerTest
{
private readonly DummyDbContext _context;
private readonly Mock<UserManager<IdentityUser>> _userManager;
private readonly Mock<SignInManager<IdentityUser>> _signInManager;
private readonly Mock<IUserRepository> _userRepository;
private readonly UserController _controller;
public UserControllerTest()
{
_context = new DummyDbContext();
_userManager = new Mock<UserManager<IdentityUser>>(
new Mock<IUserStore<IdentityUser>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<IdentityUser>>().Object,
new IUserValidator<IdentityUser>[0],
new IPasswordValidator<IdentityUser>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
new Mock<IServiceProvider>().Object,
new Mock<ILogger<UserManager<IdentityUser>>>().Object);
_signInManager = new Mock<SignInManager<IdentityUser>>(
_userManager.Object,
new Mock<IHttpContextAccessor>().Object,
new Mock<IUserClaimsPrincipalFactory<IdentityUser>>().Object,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<ILogger<SignInManager<IdentityUser>>>().Object,
new Mock<IAuthenticationSchemeProvider>().Object);
_userRepository = new Mock<IUserRepository>();
_controller = new UserController(_userRepository.Object, _userManager.Object, _signInManager.Object);
}
[Fact]
public async void Index_GetModelContainingAllUsers()
{
_userRepository.Setup(g => g.GetAll()).Returns(_context._dbsetUsers.Object);
var actionResult = await _controller.Index() as Task<ViewResult>;
var usersResult = actionResult?.Result?.Model as IEnumerable<User>;
foreach (var g in usersResult) {
Console.WriteLine(g.Username);
}
Assert.Equal(4, usersResult.Count());
}
现在,问题是 usersResult 为空。我不知道为什么;我在设置 userRepository 时做错了吗?
坦率地说,我觉得我做错了什么,不得不为应该是一个简单的模拟的东西编写所有这些代码。
【问题讨论】:
-
您可以先在测试中直接测试您想要测试的行。然后你可以将调用分成两行并调试测试。
-
为什么不用内存数据库?
-
@Nikolaus:我不确定你的意思,你的意思是拆分 ToAsyncList 和 GetAll 调用?
-
@H. Herzl:我该怎么做呢?坦率地说,我认为 DummyDbContext 正是如此
标签: asp.net entity-framework-core moq