使用DbEntityEntry和DbPropertyEntry测试双打 [英] Using Test Doubles with DbEntityEntry and DbPropertyEntry

查看:315
本文介绍了使用DbEntityEntry和DbPropertyEntry测试双打的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在EF6中使用新的测试双打,如这里从MSDN VS2013与Moq& NUnit的。
一直都很好,直到我不得不这样做:


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


然后:


myFoo.Name =Bar;


然后:


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


此时,我收到错误:


附加信息:不能为
属性Name调用会员'IsModified',因为
'Foo'的实体不存在在上下文中。要添加
实体到上下文调用
DbSet的添加或附加方法。


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



我从文章中创建了FakeDbSet(或TestDbSet)。我把每个FakeDbSet放在FakeContext的构造函数中,每个都被初始化。像这样:


Foos = new FakeDbSet&Foo>(); 我的问题是,是否可以使用FakeDbSet和FakeContext与测试双重情景以这种方式访问​​DbEntityEntry和DBPropertyEntry从测试双?谢谢!

解决方案


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


有效的是,你只添加了一个 ObservableCollection context.Entry 方法比这更深入。它需要更改跟踪器才能积极参与添加,修改和删除实体。如果你想模拟这个变更跟踪器,那么<​​code> ObjectStateManager (忽略了它不是被设计为嘲笑的事实),祝你好运!它有超过4000行代码。



坦白说,我不明白所有这些关于嘲笑EF的博客和文章。只有许多 LINQ to object和LINQ to entites 之间的差异应该足以阻止它。这些模拟上下文和 DbSet 构建了一个全新的宇宙,这本身就是一个bug。我已经决定进行集成测试,只有在EF参与我的代码的时间和地点。一个工作的端到端测试给了我一个坚实的感觉,事情是可行的。单元测试(伪造EF)没有。 (其他人,不要误会我)。



但是我们假设你还是想冒昧地嘲笑 DbContext.Entry&T ;




  • 方法不是虚拟的

  • 它返回一个 DbEntityEntry< T> ,一个内部构造函数的类,它是围绕 InternalEntityEntry 的包装器,它是一个内部类。而且,顺便说一下, DbEntityEntry 没有实现一个接口。



所以,回答你的问题


是否可以(...)从测试双对象访问DbEntityEntry和DBPropertyEntry?不,EF的嘲笑钩只是非常肤浅,你永远不会接近EF真正的工作原理。


I am using the new Test Doubles in EF6 as outlined here from MSDN . VS2013 with Moq & nUnit. All was good until I had to do something like this:

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

and then:

myFoo.Name = "Bar";

and then :

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

At this point is where I get an error:

Additional information: Member 'IsModified' cannot be called for property 'Name' because the entity of type 'Foo' does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet.

Although, When I examine the 'Foos' in the context with an AddWatch I can see all items I Add'ed before running the test. So they are there.

I have created the FakeDbSet (or TestDbSet) from the article. I am putting each FakeDbSet in the FakeContext at the constructor where each one gets initialized. Like this:

Foos = new FakeDbSet<Foo>();

My question is, is it possible to work with the FakeDbSet and the FakeContext with the test doubles scenario in such a way to have access to DbEntityEntry and DBPropertyEntry from the test double? Thanks!

解决方案

I can see all items I Add'ed before running the test. So they are there.

Effectively, you've only added items to an ObservableCollection. The context.Entry method reaches much deeper than that. It requires a change tracker to be actively involved in adding, modifying and removing entities. If you want to mock this change tracker, the ObjectStateManager (ignoring the fact that it's not designed to be mocked at all), good luck! It's got over 4000 lines of code.

Frankly, I don't understand all these blogs and articles about mocking EF. Only the numerous differences between LINQ to objects and LINQ to entites should be enough to discourage it. These mock contexts and DbSets build an entirely new universe that's a source of bugs in itself. I've decided to do integrations test only when and wherever EF is involved in my code. A working end-to-end test gives me a solid feeling that things are OK. A unit test (faking EF) doesn't. (Others do, don't get me wrong).

But let's assume you'd still like to venture into mocking DbContext.Entry<T>. Too bad, impossible.

  • The method is not virtual
  • It returns a DbEntityEntry<T>, a class with an internal constructor, that is a wrapper around an InternalEntityEntry, which is an internal class. And, by the way, DbEntityEntry doesn't implement an interface.

So, to answer your question

is it possible to (...) have access to DbEntityEntry and DBPropertyEntry from the test double?

No, EF's mocking hooks are only very superficial, you'll never even come close to how EF really works.

这篇关于使用DbEntityEntry和DbPropertyEntry测试双打的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆