How do I go about unit testing with Entity Framework and Moq?

后端 未结 1 893
旧巷少年郎
旧巷少年郎 2021-02-06 05:29

I\'m new to Moq, and wanting to use it like a backing store for data - but without touching the live database.

My setup is as follows:

  • A UnitOfWork contain
相关标签:
1条回答
  • 2021-02-06 06:36

    You just need to create a collection to act as the backing store and mock the enumeration db set with the backing collection

    public class MockDbSet<TEntity> : Mock<DbSet<TEntity>> where TEntity : class {
        public MockDbSet(List<TEntity> dataSource = null) {
            var data = (dataSource ?? new List<TEntity>());
            var queryable = data.AsQueryable();
    
            this.As<IQueryable<TEntity>>().Setup(e => e.Provider).Returns(queryable.Provider);
            this.As<IQueryable<TEntity>>().Setup(e => e.Expression).Returns(queryable.Expression);
            this.As<IQueryable<TEntity>>().Setup(e => e.ElementType).Returns(queryable.ElementType);
            this.As<IQueryable<TEntity>>().Setup(e => e.GetEnumerator()).Returns(() => queryable.GetEnumerator());
            //Mocking the insertion of entities
            this.Setup(_ => _.Add(It.IsAny<TEntity>())).Returns((TEntity arg) => {
                data.Add(arg);
                return arg;
            });
    
            //...the same can be done for other members like Remove
        }
    }
    

    So now you can use a list to hold the data

    // ARRANGE
    var dataSource = new List<User>(); //<-- this will hold data
    var user = new User()
    {
        FirstName = "Some",
        LastName = "Guy",
        EmailAddress = "some.guy@mockymoqmoq.com",
    };
    
    var mockSet = new MockDbSet<User>(dataSource);
    var mockContext = new Mock<WebAPIDbContext>();
    
    mockContext.Setup(c => c.Set<User>()).Returns(mockSet.Object);
    
    // ACT
    using (var uow = UnitOfWork.Create(mockContext.Object))
    {
        uow.UserRepository.Add(user);
        uow.SaveChanges();
    
    
        // ASSERT
        mockSet.Verify(u => u.Add(It.IsAny<User>()), Times.Once());
        Assert.IsTrue(dataSource.Contains(user)); //<-- shows mock actually added item
        Assert.IsTrue(uow.UserRepository.Any(u => u == user)); //<-- show you can actually query mock DbSet
    }
    
    0 讨论(0)
提交回复
热议问题