1

我们正在尝试对依赖于 Entity Framework 4.1 的代码进行单元测试。我看过几篇针对 POCO 实施单元测试的帖子,但我们希望保留默认的 EF 管道,以便我们可以轻松使用EF Caching Wrapper

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实际上确实被调用了?

谢谢!

4

2 回答 2

1

您需要将上下文的电子邮件属性设置为假的:

var context = A.Fake<IMyEntities>();
var mail = A.Fake<WhateverTypeTheEmailPropertyHas>();
A.CallTo(() => context.Email).Returns(mail);

var email = A.Fake<Email>(context);
// ... code to configure email goes here ...
email.SendEmails();

// this fails with a FakeItEasy.ExpectationException...
A.CallTo(() => mail.AddObject(email)).MustHaveHappened();

现在我想它应该可以工作。

于 2011-08-19T20:05:14.050 回答
0

我找到了一个我并不喜欢的解决方法,但它确实有效。您可以在数据上下文本身上调用已弃用的方法,而不是调用AddObject()子对象。AddTo[Collection Name]()由于这只是一个浅层方法调用,因此可以通过 FakeItEasy 轻松评估。

我的代码更改为:

public void SendEmails()
{
    // ... code to send emails goes here...
    _dataContext.AddToEmails(this);
    _dataContext.SaveChanges();
}

然后,在我的单元测试中:

A.CallTo(_dataContext).Where(m => m.Method.Name == "AddToEmails").MustHaveHappened();
A.CallTo(() => _dataContext.SaveChanges()).MustHaveHappened();

当然,这样做的缺点是,每当您想添加到数据上下文的集合中时,总是会忽略首选的、未弃用的方法。更不用说,稍后我很有可能会因为需要确定子对象方法的执行而被绊倒......

如果有人知道更好的方法,请分享!

谢谢,

埃里克

于 2011-08-14T17:10:19.557 回答