Как проверить метод в XUnit, который нуждается в UserManager, но использует базу данных памяти - PullRequest
0 голосов
/ 01 апреля 2020

Я использую ASP. NET CORE 3.1 и XUnit для своих модульных тестов.

Я создал класс DbFactory, который создает версию InMemory моей базы данных

   public static class DbContextFactory
{
    public static ApplicationDbContext CreateDbContext()
    {
        var options = new DbContextOptionsBuilder<ApplicationDbContext>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .Options;

        var modelBuilder = new ModelBuilder(new ConventionSet());

        var dbContext = new ApplicationDbContext(options);

        var onModelCreatingMethod = dbContext.GetType().GetMethod("OnModelCreating",
            BindingFlags.Instance | BindingFlags.NonPublic);

        onModelCreatingMethod.Invoke(dbContext,
            new object[] { modelBuilder });

        return dbContext;
    }


}

Это текущий тестовый класс, который я пытаюсь использовать

public class AdminServiceTests
    {
        public ApplicationDbContext context { get; set; }
        public IAdminService adminService { get; set; }


        public AdminServiceTests()
        {
            this.context = DbContextFactory.CreateDbContext();


            this.adminService = new AdminService(userManager, context);
        }

        [Fact]
        public async Task DeleteUserShouldDeleteUser()
        {
            //What to do ???
        }
    }

Чтобы протестировать службу администратора, мне нужно предоставить менеджера пользователей. Он должен быть связан с базой данных, которую я сейчас создал.

Как я могу это сделать?

1 Ответ

0 голосов
/ 01 апреля 2020

Вы делаете распространенную ошибку при тестировании фреймворка. Все, что вам нужно сделать, это убедиться, что AdminService.DeleteUser вызывает UserManager.DeleteAsync. Пошло ли это к фактическому удалению пользователя из базы данных, это 1) не забота службы и 2) подробности реализации как ASP. NET Core Identity, так и EF Core, оба из которых имеют свои собственные обширные наборы тестов, чтобы убедиться, что это происходит.

Таким образом, вы можете просто использовать библиотеку, такую ​​как Moq, чтобы создать макет UserManager<TUser>, а затем сделать что-то вроде:

userManagerMock.Verify(x => x.DeleteAsync(user), Times.Once());

Это стоит упоминание здесь, что это также служит, чтобы указать на небольшую ошибку в этом виде дизайна. У вас есть зависимость от ASP. NET Core Identity, независимо от того, поместите ли вы вокруг него оболочку AdminService. Если ваш сервис не делает что-то особенное, кроме проксирования здесь UserManager (например, координация нескольких действий, например, удаление пользователя, инициирует уведомление или что-то в этом роде), то ваш сервис не имеет смысла, и вы должны просто использовать UserManager напрямую. Разработчики постоянно совершают такую ​​ошибку; абстракция ради абстракции только вредит вашему коду. Это добавляет дополнительные проблемы обслуживания, проблемы тестирования и скрывает, что на самом деле делает код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...