Asp.Net Mocking Репозиторий, который возвращает DbSet с .GetAll (). ToListAsync () - PullRequest
1 голос
/ 20 мая 2019

В моем приложении 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 (), поэтому я создаю DummyDbContext, используя https://github.com/romantitov/MockQueryable, чтобы помочь имитировать хранилище.

Релевантнокод:

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?

Честно говоря, я чувствую, что делаю что-то не так, когда пишу весь этот код просто для чего-то, что должно быть простым издевательством.

1 Ответ

0 голосов
/ 20 мая 2019

Мне удалось решить мою собственную проблему.

Проблема заключалась в том, что я приводил результат _controller.Index () в качестве Задачи, тогда как вместо этого я должен был приводить его как ViewResult.Когда задача завершена («ожидаю»), я получаю ViewResult, который назначается для actionResult.Приведя его в качестве Задачи, я получил ноль.

Вот что он должен был прочитать:

 [Fact]
    public async void Index_GetModelContainingAllUsers()
    {
        _userRepository.Setup(g => g.GetAll()).Returns(_context._dbsetUsers.Object);
        var actionResult = await _controller.Index() as ViewResult;
        var usersResult = actionResult?.Model as IEnumerable<User>;
        Assert.Equal(4, usersResult.Count());
    }
...