如何在模拟的IQueryable对象上实现Count方法

时间:2019-01-15 21:55:44

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

当前,我正在使用以下方法模拟DbSet:

//Helper Function in another file
public static DbSet<T> MockDbSet<T>(params T[] items) where T : class
            {
                IEnumerable<T> ts = items;
                var mock = new Mock<DbSet<T>>();
                mock.As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(ts.GetEnumerator());
                return mock.Object;
            }

而我使用的是它:

Answer[] sampleAnswers = new Answer[]
                {
                    new Answer() { Id = 4, QuestionId = 1, SurveyId = 4 },
                    new Answer() { Id = 5, QuestionId = 2, SurveyId = 4 },
                    new Answer() { Id = 6, QuestionId = 3, SurveyId = 4 },
                    new Answer() { Id = 7, QuestionId = 4, SurveyId = 5 }
                };

var mockAnswers = Helper.MockDbSet(sampleAnswers);

context.Setup(c => c.Answers).Returns(mockAnswers);
var count = context.Object.Answers.Count();

当我进入context.Object.Answers.Count()时,我得到一个空指针异常。但是,当我在context.Object.Answers上运行foreach时,我可以很好地得到每个答案。有什么我需要模仿的东西吗?我知道我不能模拟扩展方法。

1 个答案:

答案 0 :(得分:1)

Servy的答案是正确的,我需要将我的通用DbSet更改为以下内容并计算有效:

 public static DbSet<T> MockDbSet<T>(params T[] items) where T : class
    {
        IEnumerable<T> ts = items;
        var mock = new Mock<DbSet<T>>();
        mock.As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(ts.GetEnumerator());
        mock.As<IQueryable<T>>().Setup(x => x.Provider).Returns(items.AsQueryable().Provider);
        mock.As<IQueryable<T>>().Setup(x => x.Expression).Returns(items.AsQueryable().Expression);
        mock.As<IQueryable<T>>().Setup(x => x.ElementType).Returns(items.AsQueryable().ElementType);

        return mock.Object;
    }