【问题标题】:Should I mock the entities of EF when unit testing?单元测试时我应该模拟 EF 的实体吗?
【发布时间】:2012-11-29 02:34:47
【问题描述】:

我读过this post about mocking Entity Framework(EF)

我们不应该也抽象实体的类型吗?为了保持数据访问层 (DAL) 和业务层 (BL) 之间的解耦?

在上面的帖子中,他使用了 EF 具体生成的实体类型:

[TestMethod]
public void GetCustomer()
{
    ContextContainerMock container = new ContextContainerMock();
    IMyEntities en = container.Current;

**Customer c = new Customer { ID = 1, FirstName = "John", LastName = "Doe" };**
    en.Customers.AddObject(c);

    CustomerService service = new CustomerService(container);
    var a = service.GetCustomer(1);

    Assert.AreEqual(c.FirstName, a.FirstName);
    Assert.AreEqual(c.LastName, a.LastName);
}

【问题讨论】:

    标签: c# visual-studio-2010 unit-testing entity-framework-4 rhino-mocks


    【解决方案1】:

    就我个人而言,我不会嘲笑这些。我直接创建、测试和清理。这帮助我在处理数据库时发现了更真实世界场景的问题。模拟非常适合测试您可能无法访问数据库等资源的集成。如果这是你的情况,那么你可能别无选择。希望有帮助。

    【讨论】:

    • 我想模拟单元测试。如果我抽象实体类型,我将如何实现entities.SaveChanges()
    • 正如我所说,我不会模拟这些用于单元测试。我不认为嘲笑它的价值会带来积极的回报。针对数据库的真实实例进行单元测试,而不是模拟它。如果您绝对想模拟保存更改,则需要模拟持久化数据。为此,您可以使用内存数据库。
    【解决方案2】:

    简短的回答是否定的。

    如果正确完成,实体不依赖于任何其他代码,除了其他实体和值对象(例如字符串、int 或您自己的值对象)。因此,没有必要模拟它们。

    此外,实体是系统核心的一部分。它们就是您的系统的全部内容。您通常希望测试系统在操作这些类时的行为,而不是测试系统在操作测试所说的它们的行为时的行为。

    (作为旁注,您的实体应该看起来和行为类似于现实世界中存在的东西。也就是说,您应该能够从业务方面与非技术人员推理行为组织。从您的示例中,我看到可以创建没有名称的客户。从业务角度来看可以吗?如果不是,我会说您应该让构造函数将名字和姓氏作为参数。 )

    【讨论】:

    • 但是BLDAL 将与 EF 特定技术紧密耦合
    • EF 是你的 DAL,所以没关系。不过BL不应该知道任何关于EF的事情。 IMyEntities 属于 BL 并且是免费的,而 MyEntities 属于 DAL 并且包含 EF 代码。
    • 我错过了一些东西。 DAL 方法public Clients GetAllClients() 将返回什么。不是Clients EF 类型吗?所以BL 必须知道吗?
    • Clients 是一个实体,属于 BL。但是,DAL/EF 负责持久化Clients。所以 EF 了解Clients,但这并不意味着它拥有它或者它是 EF 的类型。 UI 可能也知道Clients,但它也不属于 UI。
    • 我的意思是存在不必要的耦合。 EFEntity.Client 穿过所有应用层。如果我们将 DAL 技术从 EF 更改为 Nhibernate - 我们还必须编译 BL 并相应地更改所有单元测试(因为你,以及依赖 EF 生成的类型)\
    猜你喜欢
    • 1970-01-01
    • 2014-07-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 2016-07-23
    相关资源
    最近更新 更多