Mocked DbSet, похоже, не работает как задумано - PullRequest
0 голосов
/ 24 сентября 2019

Я создаю веб-API с использованием .Net Core.Во время тестирования одного из моих сервисных методов я столкнулся с проблемой, когда при вызове Remove () в mocked DbSet не удаляется объект, который он должен удалить.После возврата bool, который является простым, Contains () проверяет мой набор.

Пробовал издеваться над ним разными способами, но ни один из них, похоже, не работает

Мой помощник DbSet Mock:

public static Mock<DbSet<T>> CreateDbSetMock<T>(IEnumerable<T> elements) where T : class
        {
            var elementsAsQueryable = elements.AsQueryable();
            var dbSetMock = new Mock<DbSet<T>>();

            dbSetMock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(elementsAsQueryable.Provider);
            dbSetMock.As<IQueryable<T>>().Setup(m => m.Expression).Returns(elementsAsQueryable.Expression);
            dbSetMock.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(elementsAsQueryable.ElementType);
            dbSetMock.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(elementsAsQueryable.GetEnumerator());

            return dbSetMock;
        }
    }

Мой метод, который я хочу проверить:

public virtual async Task<bool> DeleteSupplierAsync(User user)
        {
            var currentRoles = await _userManagerWrap.GetRolesForUser(_userManager, user);
            if (!currentRoles.Contains(nameof(Role.Supplier)))
            {
                throw new ArgumentException("Provided user does not belong to Suppliers");
            }
            var brand = GetBrandForUser(user);
            if (brand != default(Brand))
            {
                var users = _context.Users.Where(e => e.BrandId == brand.Id).ToList();
                _context.Users.RemoveRange(users);
                _context.Brands.Remove(brand);
            }
            else
            {
                _context.Users.Remove(user);
            }
            await _context.SaveChangesAsync();
//In the next line Users still contains the user i want to remove
            return !_context.Users.Contains(user);
        }

Мой тест:

public async Task DeleteSupplierAsyncTest(IList<string> rolesToReturn, Brand brandToReturn, List<User> usersToReturn, List<Brand> brandsToReturn, string userIdToDelete, bool expectedException, string expectedMessage, bool expectedResult)
        {
            var userManagerMock = new Mock<UserManagerWrap>();
            userManagerMock.Setup(m => m.GetRolesForUser(It.IsAny<UserManager<User>>(), It.IsAny<User>())).Returns(Task.FromResult(rolesToReturn));

            var appDbContextMock = new Mock<AppDbContext>();

            var userTableMock = TestsHelper.CreateDbSetMock(usersToReturn);
            var brandsTableMock = TestsHelper.CreateDbSetMock(brandsToReturn);

            appDbContextMock.Setup(m => m.Users).Returns(userTableMock.Object);
            appDbContextMock.Setup(m => m.Brands).Returns(brandsTableMock.Object);

            var userServiceMock = new Mock<UserService>(appDbContextMock.Object, null, null, new Mock<IOptions<TokenSettings>>().Object, null, null, new Mock<IOptions<AzureAdClaimTypes>>().Object, userManagerMock.Object, null, null) { CallBase = true };

            userServiceMock.Setup(m => m.GetBrandForUser(It.IsAny<User>())).Returns(brandToReturn);

            if (expectedException)
            {

                var ex = Assert.ThrowsAsync(Is.AssignableTo(typeof(Exception)), () => userServiceMock.Object.
                DeleteSupplierAsync(null));
                Assert.AreEqual(expectedMessage, ex.Message);
            }
            else
            {
                var user = userTableMock.Object.First(x => x.Id == userIdToDelete);

                var result = await userServiceMock.Object.DeleteSupplierAsync(user);
                Assert.AreEqual(expectedResult, result);
            }
        }

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

...