收集被修改,枚举操作可能不会在Moq中用EF执行

Ank*_*ana 1 c# unit-testing entity-framework in-memory-database

在进行单元测试时,我无法在dbset中添加新实体后从dbset中收集回来,它会抛出异常' Collection was modified '

这是我的代码设置

[TestMethod]
[TestCategory("Skill Category")]
public void Create_Skill_Category()
{
    var category = new SkillCategoryModel() { CategoryId = 3, CategoryName = "Category 3" };
    var result = skillManager.SaveSkillCategory(category);
    Assert.IsNotNull(result, "Category can't be null");
    Assert.AreEqual(category.CategoryId, result.CategoryId, "Category id must be equal");
    var categoryList = skillManager.GetCategories(); // here exception thrown
    Assert.IsTrue(categoryList.Count == 3, "Categories List must be contain three category");
}


private ISkill skillManager;
[TestInitialize]
public void Init()
{
    var category = new SkillCategory { CategoryId = 1, CategoryName = "Category 1" };

    var categories = new List<SkillCategory>
    { 
        category,
        new SkillCategory { CategoryId = 2, CategoryName = "Category 2" }
    };
    var categoryMockSet = Utility.GenerateMockEntity(categories);
    categoryMockSet.Setup(x => x.Add(It.IsAny<SkillCategory>())).Callback<SkillCategory>(x => categories.Add(x)).Returns<SkillCategory>(x => x);
    var mock = new Mock<WhoEntities>();
    mock.Setup(q => q.SkillCategories).Returns(categoryMockSet.Object);
    mock.CallBase = true;
    skillManager = new WhoGroup.DML.Managers.SkillManager(mock.Object);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我无法理解我做错了什么.供参考我正在使用此链接:

实体框架6和Moq4:是否有可能让模拟的DbSet在其范围的持续时间内保留添加的数据?

Flo*_*n K 7

以下陈述不正确:

entityMockSet.As<IEnumerable<TEntity>>()
    .Setup(m => m.GetEnumerator()).Returns(query.GetEnumerator());
Run Code Online (Sandbox Code Playgroud)

Enumerator每个请求都会返回相同的内容,这会导致您只能使用枚举器一次,因为之后没有任何项目.

部分解决问题的方法是每次调用时都会重置枚举器GetEnumerator,因为你只能使用Add-Method

解决方案: 真正解决问题的方法是在设置GetEnumerator方法时使用Lambda:

entityMockSet.As<IEnumerable<TEntity>>()
    .Setup(m => m.GetEnumerator()).Returns(() => query.GetEnumerator());
Run Code Online (Sandbox Code Playgroud)

这一部分非常重要: .Returns(()=> query.GetEnumerator()); 因为每次发出请求时都会返回一个新的枚举器.