Как издеваться над UserManager <IdentityUser> - PullRequest
4 голосов
/ 29 марта 2019

Я пытаюсь понять, как добавить модульное тестирование в мой проект. Я подумал, что лучше всего начать с пустого проекта и решить его с самого начала, а не добавлять его в мой основной проект. Как только я пойму процесс, который, как я понимаю, я могу начать рефакторинг своего проекта для добавления тестирования.

веб-приложение

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

Это дало мне старт, похожий на это

public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

Затем я создал простой контроллер и передал usermanager в конструктор.

[Route("api/[controller]")]
[ApiController]
public class SweetController : ControllerBase
{
    private readonly UserManager<IdentityUser> _userManager;

    public SweetController(UserManager<IdentityUser> userManager)
    {
        _userManager = userManager;
    }
    public async Task<int> NumberOfGummyBearsForUser(string userId)
    {
        var user = await _userManager.FindByIdAsync(userId);
        var userHasASweetTooth = await _userManager.IsInRoleAsync(user, "SweetTooth");
        if (userHasASweetTooth)
        {
            return 100;
        }
        else
        {
            return 1;
        }
    }
}

Модульный тест

Первое, что я пытался сделать, - это посмеяться над этим менеджером пользователей, но он не работает.

public void Test1()
    {
        // Arrange
        var mockUser = new Mock<UserManager<IdentityUser>>();
        var userManager = new UserManager(mockRepo.Object);  <-- error here see image below

        var controller = new SweetController(userManager.Object);

        // Act
        var result = await controller.NumberOfGummyBearsForUser("123");

        // Assert
        Assert.Equal(100, result);
    }

Ошибка выглядит следующим образом

enter image description here

Я думаю, что мне нужно пройти еще больше, чтобы создать этот объект usermanager, но я не уверен, что все учебники, которые я нашел, используют ApplicationUser, а не IdentityUser, поэтому я не знаю, как я могу насмехаться над этим объектом.

Ответы [ 2 ]

6 голосов
/ 29 марта 2019

Вы просто делаете

// Arrange
var mockUser = new Mock<UserManager<IdentityUser>>();

var controller = new SweetController(mockUser.Object);

Вам вообще не нужно

var userManager = new UserManager(mockRepo.Object);  <-- error here see image below

.mockUser - это уже смоделированный UserManager<T>, который вы помещаете в макетированный экземпляр с помощью mock.Object.

Когда вы макете объект, вам не нужно создавать его экземпляр со всеми его зависимостями (это было бытест на интеграцию), в этом суть насмешки (наряду с созданием методов, возвращающих желаемое значение, и проведением поведенческих тестов, чтобы убедиться, что в тестируемом коде был вызван определенный метод с определенным параметром проверяемого объекта).

КонечноПо сути, приведенный выше код не будет работать, так как вы не установили никаких условий тестирования / возвратов для FindByIdAsync и IsInRoleAsync.Вы должны настроить их с помощью

mockUser.Setup( userManager => userManager.FindByIdAsync(It.IsAny<string>()))
    .ReturnsAsync(new IdentityUser { ... });
mockUser.Setup( userManager => userManager.IsInRoleAsync(It.IsAny<IdentityUser>(), "SweetTooth"))
    .ReturnsAsync(true);

Затем, когда вызывается макет, он возвращает вашего предопределенного пользователя и предопределенный результат.

0 голосов
/ 29 марта 2019

С помощью Ценга я заработал. Полностью рабочая версия этого

* 1003 контроллер * private readonly UserManager<IdentityUser> _userManager; public SweetController(UserManager<IdentityUser> userManager) { _userManager = userManager; } public async Task<IdentityUser> GetUser(string userId) { var user = await _userManager.FindByIdAsync(userId); return user; } Test

[Fact]
    public async Task Test1()
    {
        // Arrange
        var store = new Mock<IUserStore<IdentityUser>>();
        store.Setup(x => x.FindByIdAsync("123", CancellationToken.None))
            .ReturnsAsync(new IdentityUser()
            {
                UserName = "test@email.com",
                Id = "123"
            });

        var mgr = new UserManager<IdentityUser>(store.Object, null, null, null, null, null, null, null, null);

        var controller = new SweetController(mgr);

        // Act
        var result = await controller.GetUser("123");

        // Assert
        Assert.NotNull(result);
        Assert.Equal("123", result.Id);
    }

Я удалил проверку роли, чтобы она работала как можно более простой.

...