39

我是针对 ADO .NET Entity Framework 编写的单元测试代码。我想用行填充内存数据库,并确保我的代码正确检索它们。

我可以使用 Rhino Mocks 模拟实体框架,但这还不够。我会告诉查询返回给我的实体。这既不会测试 where 子句也不会测试 .Include() 语句。我想确保我的 where 子句只匹配我想要的行,而不匹配其他行。我想确定我已经要求了我需要的实体,而没有我不需要的实体。

例如:

class CustomerService
{
    ObjectQuery<Customer> _customerSource;
    public CustomerService(ObjectQuery<Customer> customerSource)
    {
        _customerSource = customerSource;
    }
    public Customer GetCustomerById(int customerId)
    {
        var customers = from c in _customerSource.Include("Order")
            where c.CustomerID == customerId
            select c;
        return customers.FirstOrDefault();
    }
}

如果我模拟 ObjectQuery 以返回填充了订单的已知客户,我怎么知道 CustomerService 具有正确的 where 子句和 Include?我宁愿插入一些客户行和一些订单行,然后断言选择了正确的客户并填充了订单。

4

8 回答 8

16

EF7(预发行版)中包含一个 InMemory 提供程序。

您可以使用NuGet 包,也可以在 GitHub 上的EF 存储库中阅读它(查看源代码)。

于 2015-04-30T19:20:37.553 回答
13

文章 http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort  描述 了在内存中运行的Effort   -Entity Framework 提供程序。

您仍然可以在单元测试中使用 DbContext 或 ObjectContext 类,而无需拥有实际的数据库。

于 2012-12-29T06:34:23.857 回答
9

这里更好的方法可能是使用存储库模式来封装您的 EF 代码。在测试你的服务时,你可以使用 mocks 或 fakes。在测试存储库时,您需要访问真实数据库以确保获得预期的结果。

于 2009-02-22T18:54:53.463 回答
7

当前没有 EF 的内存提供程序,但如果您查看 Highway.Data,它有一个基本抽象接口和一个 InMemoryDataContext。

使用 Highway.Data 测试数据访问和 EF

于 2014-05-16T00:16:58.457 回答
6

是的,至少有一个这样的提供程序 - SQLite。我已经使用了一点,它的工作原理。您也可以尝试SQL Server Compact。它是一个嵌入式数据库,也有 EF 提供程序。
编辑:
SQLite 支持内存数据库(link1)。您只需要指定一个连接字符串,例如:“Data Source=:memory:;Version=3;New=True;”。如果您需要一个示例,您可以查看SharpArchitecture

于 2009-02-22T18:36:56.737 回答
2

我不熟悉 Entity Framework 和 ObjectQuery 类,但如果 Include 方法是虚拟的,您可以像这样模拟它:

// Arrange
var customerSourceStub = MockRepository.GenerateStub<ObjectQuery<Customer>>();
var customers = new Customer[] 
{
    // Populate your customers as if they were coming from DB
};
customerSourceStub
    .Stub(x => x.Include("Order"))
    .Return(customers);
var sut = new CustomerService(customerSourceStub);

// Act
var actual = sut.GetCustomerById(5);

// Assert
Assert.IsNotNull(actual);
Assert.AreEqual(5, actual.Id);
于 2009-02-22T16:53:44.800 回答
1

您可以尝试SQL Server Compact,但它有一些非常严重的限制:

  • 与实体框架一起使用时,SQL Server Compact 不支持分页查询中的 SKIP 表达式
  • SQL Server Compact 在与实体框架一起使用时不支持具有服务器生成的键或值的实体
  • 没有外部连接、整理、对浮点数、聚合取模
于 2009-02-23T08:31:14.280 回答
0

EF Core中,执行此操作有两个主要选项:

  1. SQLite 内存模式允许您针对行为类似于关系数据库的提供程序编写有效的测试。
  2. InMemory 提供程序是一个轻量级提供程序,具有最小的依赖关系,但并不总是像关系数据库一样运行

我正在使用 SQLite,它支持所有查询,我需要使用 Azure SQL 生产数据库。

于 2018-01-25T12:07:49.003 回答