2016-11-29 65 views
0

虽然做单元测试,我不能够得到收集从dbset早在dbset添加新的实体后,它抛出一个异常“集合被修改集合被修改,枚举操作可能不会起订量EXCUTE与EF

这里是我的代码设置

[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); 
} 

这里我不能够理解我做什么错在这种情况下。 参考我使用这个链接:在MOQ Dbset,因为我不是在DB组添加新的实体后更新的GetEnumerator的参考发生

Entity Framework 6 and Moq4: Is it possible to have a mocked DbSet retain added data for the duration of its scope?

回答

4

目前提供的答案不正确。 它只能部分解决问题。
下列说法不正确的是:

entityMockSet.As<IEnumerable<TEntity>>() 
    .Setup(m => m.GetEnumerator()).Returns(query.GetEnumerator()); 

返回为每个请求,这导致了问题,你可以使用枚举只一次,因为它有它没有项目后同样Enumerator

什么部分解决了这个问题是调用它解决它为你,因为你只能使用Add - 方法

解决方案的GetEnumerator当每次重置枚举: 真正解决问题是使用的λ时建立GetEnumerator方法:

entityMockSet.As<IEnumerable<TEntity>>() 
    .Setup(m => m.GetEnumerator()).Returns(() => query.GetEnumerator()); 

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

+1

谢谢,回复 –

0

错误。

public class Utility 
    { 
     public static Mock<DbSet<TEntity>> GenerateMockEntity<TEntity>(List<TEntity> entityList) where TEntity : class 
     { 
      var list = new List<TEntity>(); 
      list.AddRange(entityList); 
      var query = list.AsQueryable(); 
      var entityMockSet = new Mock<DbSet<TEntity>>() { CallBase = true}; 
      entityMockSet.As<IQueryable<TEntity>>().Setup(m => m.Provider).Returns(query.Provider); 
      entityMockSet.As<IQueryable<TEntity>>().Setup(m => m.Expression).Returns(query.Expression); 
      entityMockSet.As<IQueryable<TEntity>>().Setup(m => m.ElementType).Returns(query.ElementType); 
      entityMockSet.As<IEnumerable<TEntity>>().Setup(m => m.GetEnumerator()).Returns(query.GetEnumerator()); 
      entityMockSet.Setup(x => x.Add(It.IsAny<TEntity>())).Callback<TEntity>(x => { 
       list.Add(x); 
       entityMockSet.As<IEnumerable<TEntity>>().Setup(m => m.GetEnumerator()).Returns(list.GetEnumerator()); 
      }).Returns<TEntity>(x => x); 
      return entityMockSet; 
     } 
    } 
+0

这只适用于你只使用Add方法,并且不要做任何其他的foreach或类似的集合 –

相关问题