Создание экземпляра UserManager <T>в тестах - PullRequest
0 голосов
/ 28 февраля 2019

Я очень новичок в концепции насмешек, и я борюсь с введением / насмешками UserManager<T> для моих тестов

Мне нужно использовать await _userManager.CreateAsync(user, password);

Я нашелэтот

public static UserManager<TUser> TestUserManager<TUser>(IUserStore<TUser> store = null) where TUser : class
{
    store = store ?? new Mock<IUserStore<TUser>>().Object;
    var options = new Mock<IOptions<IdentityOptions>>();
    var idOptions = new IdentityOptions();
    idOptions.Lockout.AllowedForNewUsers = false;
    options.Setup(o => o.Value).Returns(idOptions);
    var userValidators = new List<IUserValidator<TUser>>();
    var validator = new Mock<IUserValidator<TUser>>();
    userValidators.Add(validator.Object);
    var pwdValidators = new List<PasswordValidator<TUser>>();
    pwdValidators.Add(new PasswordValidator<TUser>());
    var userManager = new UserManager<TUser>(store, options.Object, new PasswordHasher<TUser>(),
        userValidators, pwdValidators, new UpperInvariantLookupNormalizer(),
        new IdentityErrorDescriber(), null,
        new Mock<ILogger<UserManager<TUser>>>().Object);
    validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>()))
        .Returns(Task.FromResult(IdentityResult.Success)).Verifiable();

    return userManager;
}

Но это выдает

System.NotSupportedException: Store не реализует IUserPasswordStore.

Как создать рабочий UserManager<T> экземпляр в тестах?

Я использую Xunit

1 Ответ

0 голосов
/ 28 февраля 2019

Прежде всего, пересмотрите ваш подход, я прочитал несколько разных статей, в которых люди говорят, что вам не нужно тестировать библиотеку и инструмент, который уже был протестирован.Но иногда нам нужно издеваться над UserManager, чтобы внедрить наши сервисы и разрешить эти зависимости.UserManager может быть очень простым, но подобные сообщения об ошибках не очень хорошо объяснены.Сначала мы должны смоделировать UserStore и присвоить его UserManager, чтобы смоделировать UserStore, вы можете создать класс MockUserStore, который получает IUserStore и IUserPasswordStore:

public class MockUserStore : IUserStore<TUser>, IUserPasswordStore<TUser>

Этот класс долженреализовать некоторые методы IUserPasswordStore, в противном случае вы получите это сообщение об ошибке!

public Task SetPasswordHashAsync(TUser user, string passwordHash,
     CancellationToken cancellationToken)
{
    user.PasswordHash = passwordHash;
    return Task.FromResult(0);
}

public Task<string> GetPasswordHashAsync(TUser user, CancellationToken cancellationToken)
{
    return Task.FromResult<string>(user.PasswordHash);
}

public Task<bool> HasPasswordAsync(TUser user, CancellationToken cancellationToken)
{
    return Task.FromResult<bool>(!String.IsNullOrEmpty(user.PasswordHash));
}

Вы также можете использовать класс для макета UserManager и переопределить его методы с помощью имитированных методов:

public class MockUserManager : UserManager<TUser>
{
    public MockUserManager(IUserStore<TUser> store, IOptions<IdentityOptions> optionsAccessor,
     IPasswordHasher<TUser> passwordHasher, IEnumerable<IUserValidator<TUser>> userValidators,
      IEnumerable<IPasswordValidator<TUser>> passwordValidators, ILookupNormalizer keyNormalizer,
       IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<TUser>> logger)
        : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
    {
    }

    public override Task<IdentityResult> CreateAsync(TUser user)
    {
        return Task.FromResult(IdentityResult.Success);
    }
}

В конце концов вы можете издеваться над UserManager с попутным издевались UserStore:

    var userStore = new MockUserStore();
    var userManager = new MockUserManager(userStore,
                        new Mock<IOptions<IdentityOptions>>().Object,
                        new Mock<IPasswordHasher<AppUser>>().Object,
                        new IUserValidator<TUser>[0],
                        new IPasswordValidator<TUser>[0],
                        new Mock<ILookupNormalizer>().Object,
                        new Mock<IdentityErrorDescriber>().Object,
                        new Mock<IServiceProvider>().Object,
                        new Mock<ILogger<UserManager<TUser>>>().Object);
    return userManager;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...