我正在使用here from MSDN中概述的EF6中的新测试双打。带有Moq和nUnit的VS2013。
一切都很好,直到我不得不做这样的事情:


  var myFoo = context.Foos.Find(id);


接着:


  myFoo.Name = "Bar";


接着 :


  context.Entry(myFoo).Property("Name").IsModified = true;


此时,我得到一个错误:


  附加信息:不能要求成员“ IsModified”
  属性“名称”,因为类型的实体
  “ Foo”在上下文中不存在。要添加
  实体到上下文调用的Add或Attach方法
  DbSet。


虽然,当我使用AddWatch检查上下文中的“ Foos”时,我可以在运行测试之前看到我添加的所有项目。所以他们在那里。

我已经从本文创建了FakeDbSet(或TestDbSet)。我将每个FakeDbSet放置在FakeContext中的构造函数中,在每个构造函数处对其进行初始化。像这样:


  Foos = new FakeDbSet<Foo>();


我的问题是,是否可以将FakeDbSet和FakeContext与测试双打场景一起使用,从而可以从测试双打访问DbEntityEntry和DBPropertyEntry?谢谢!

最佳答案

在运行测试之前,我可以看到我添加的所有项目。所以他们在那里。


实际上,您仅将项目添加到了ObservableCollectioncontext.Entry方法的意义远不止于此。它要求变更跟踪器积极参与添加,修改和删除实体。如果您想模拟这个变更跟踪器,请ObjectStateManager(忽略它并非完全被模拟的事实),祝您好运!它有超过4000行代码。

坦白说,我不了解所有有关模拟EF的博客和文章。只有大量的differences between LINQ to objects and LINQ to entites应该足以阻止它。这些模拟上下文和DbSet构建了一个全新的Universe,它本身就是错误的来源。我决定只在代码中涉及EF的任何时间和地点进行集成测试。可以进行的端到端测试使我有种确定的感觉。单元测试(伪造EF)没有。 (其他人可以,请不要误解我的意思)。

但是,让我们假设您仍然想尝试模拟DbContext.Entry<T>。太糟糕了,不可能。


该方法不是虚拟的
它返回一个DbEntityEntry<T>,一个带有内部构造函数的类,该类是对InternalEntityEntry(内部类)的包装。而且,顺便说一句,DbEntityEntry没有实现接口。


所以,回答你的问题


  是否可以(...)从测试双打访问DbEntityEntry和DBPropertyEntry?


不,EF的嘲讽只是非常肤浅,您甚至永远也不会接近EF的工作原理。

08-04 17:13