使用 FakeItEasy 针对嵌套实体框架成员进行单元测试
我们正在尝试对依赖于 Entity Framework 4.1 的代码进行单元测试。我看过几篇针对 POCO 实施单元测试的帖子,但我们希望保留默认的 EF 管道,以便我们可以轻松使用 EF 缓存包装。
FakeItEasy 似乎可以很好地处理抽象 EF,但我在断言发生了什么时遇到问题。例如,我的模型中有此代码(其中有另一个 Email
部分类,它是 EF 数据库优先向导自动生成的代码):
public partial class Email
{
IMyEntities _dataContext;
public Email(IMyEntities myEntities)
{
_dataContext = myEntities;
}
public void SendEmails()
{
// ... code to send emails goes here...
_dataContext.Emails.AddObject(this);
_dataContext.SaveChanges();
}
}
然后在使用 FakeItEasy 的单元测试中:
var context = A.Fake<IMyEntities>();
var email = A.Fake<Email>(context);
// ... code to configure email goes here ...
email.SendEmails();
// this fails with a FakeItEasy.ExpectationException...
A.CallTo(() => context.Email.AddObject(email)).MustHaveHappened();
我怎样才能从我的单元测试中知道 context.Emails.AddObject
实际上确实被调用了?
谢谢你!
We are trying to unit test code that relies on the Entity Framework 4.1. I've seen several posts that implement unit testing against POCOs, but we would like to retain the default EF plumbing, so that we can easily use the EF Caching Wrapper.
FakeItEasy seems to handle abstracting away EF okay, but I'm having problems asserting what happened. For example, I have this code in my model (where there is another Email
partial class that is the autogenerated code from the EF database-first wizard):
public partial class Email
{
IMyEntities _dataContext;
public Email(IMyEntities myEntities)
{
_dataContext = myEntities;
}
public void SendEmails()
{
// ... code to send emails goes here...
_dataContext.Emails.AddObject(this);
_dataContext.SaveChanges();
}
}
Then in my unit test with FakeItEasy:
var context = A.Fake<IMyEntities>();
var email = A.Fake<Email>(context);
// ... code to configure email goes here ...
email.SendEmails();
// this fails with a FakeItEasy.ExpectationException...
A.CallTo(() => context.Email.AddObject(email)).MustHaveHappened();
How can I know from my unit test that context.Emails.AddObject
actually did get called?
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要将上下文的电子邮件属性设置为假:
现在我想它应该可以工作。
You need to set the Email-property of you context to a fake:
Now I guess it should work.
我找到了一个我并不热衷的解决方法,但它确实有效。您可以在数据上下文本身上调用已弃用的方法
AddTo[Collection Name]()
,而不是在子对象上调用AddObject()
。由于这只是一个浅层方法调用,因此可以通过 FakeItEasy 轻松对其进行评估。我的代码更改为:
然后,在我的单元测试中:
当然,这样做的缺点是,每当您想要添加到数据上下文集合时,您总是会忽略首选的、未弃用的方法。更不用说,以后我很可能会因为需要确定子对象方法的执行而被绊倒......
如果有人知道更好的方法,请分享!
谢谢你,
埃里克
I found a workaround that I'm not crazy about, but it does work. Instead of calling
AddObject()
on the child object, you can call a deprecated method,AddTo[Collection Name]()
, on the data context itself. Since this is just a shallow method call, it can be easily evaluated by FakeItEasy.My code changed to this:
Then, in my unit test:
Of course, by doing this you have the downside of always ignoring the preferred, non-deprecated, methods whenever you want to add to a collection of the data context. Not to mention, there's a good chance I'll get tripped up later on with a need to determine execution on a child object's method...
If anyone knows a better way, please share!
Thank you,
Eric