从模拟db上下文创建的EF存储库仅返回dbset一次

时间:2017-06-19 14:15:56

标签: c# entity-framework unit-testing moq

我正在为我的控制器编写单元测试。 该测试使用实际的Repository类,该类使用内部的模拟dbcontext。我正在创建这个帮助文章中的dbset,它可以正常工作 - 除了它每单元测试只能工作一次。

http://codethug.com/2015/03/20/mocking-dbset/

这意味着:

  IQueryable<User> membersQuery = this.unitOfWork.UserRepository.Get();
            List<User> members = membersQuery.ToList(); //here I get 6 members
            membersQuery = this.unitOfWork.UserRepository.Get();
             members = membersQuery.ToList(); //when its called again, I get 0 members

为什么它会像那样,我希望它能同时返回相同的成员集合。

以下是我创建存储库的方法

var enumerable = new List<User>();
// ... populate the mocks list
 var mockedContext = new Mock<MyDbContext>();
 mockedContext.Setup(c => c.Users).ReturnsDbSet(enumerable);
 mockedContext.Setup(c => c.Set<User>()).ReturnsDbSet(enumerable);
 var repo = new Mock<IRepository<User>>();           
 return new Repository<User>(mockedContext.Object, this.logger);

为清楚起见,存储库代码的一些最重要的部分:

public class Repository<TEntity> :  IRepository<TEntity> where TEntity : class
{
        protected internal MyDbContext Context;
        protected internal DbSet<TEntity> DbSet;
        public Repository(MyDbContext context)
        {
            this.Context = context;
            this.DbSet = context.Set<TEntity>();
        }

        public virtual IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null)
        {
            IQueryable<TEntity> query = this.DbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            return query;
        }

任何想法为什么会那样起作用?

1 个答案:

答案 0 :(得分:2)

基于链接的示例。所描述的问题通常是因为这条线。

mockSet.As<IQueryable<T>>()
    .Setup(m => m.GetEnumerator())
    .Returns(queryableData.GetEnumerator()); //<-- this here

返回queryableData.GetEnumerator()此处alony允许一次性转发仅枚举。

允许多个枚举返回一个函数。

mockSet.As<IQueryable<T>>()
    .Setup(m => m.GetEnumerator())
    .Returns(() => queryableData.GetEnumerator()); //<-- note the change () =>

每次需要枚举时都会调用该函数,允许多次枚举该集合。