0

我想为一个方法写一些单元测试。但是,该方法引用了我的实体框架。这是我要测试的方法的一个非常人为的示例:

public int GetNumberWithName(string name, NWRevalDatabaseEntities entities)
{
    int number = (from n in entities.TableOfNumbers
                    where n.Name == name
                    select n).First();

    return number;
}

问题:

有没有办法让我NWRevalDatabaseEntities在我的测试类中实例化一个对象而不给它一个可行的数据库连接,所以所有的表都是空的,然后只是插入测试所需的实体,而不是将它们持久化到数据库中?

存储NWRevalDatabaseEntities是一个 SQLite 数据库,可用的自动生成的构造函数是:

/// <summary>
/// Initializes a new NWRevalDatabaseEntities object using the connection string found in the 'NWRevalDatabaseEntities' section of the application configuration file.
/// </summary>
public NWRevalDatabaseEntities() : base("name=NWRevalDatabaseEntities", "NWRevalDatabaseEntities")
{
    this.ContextOptions.LazyLoadingEnabled = true;
    OnContextCreated();
}

/// <summary>
/// Initialize a new NWRevalDatabaseEntities object.
/// </summary>
public NWRevalDatabaseEntities(string connectionString) : base(connectionString, "NWRevalDatabaseEntities")
{
    this.ContextOptions.LazyLoadingEnabled = true;
    OnContextCreated();
}

/// <summary>
/// Initialize a new NWRevalDatabaseEntities object.
/// </summary>
public NWRevalDatabaseEntities(EntityConnection connection) : base(connection, "NWRevalDatabaseEntities")
{
    this.ContextOptions.LazyLoadingEnabled = true;
    OnContextCreated();
}

所有这些都需要一个连接或连接字符串(或使用存储的连接字符串)。

如果这不可能,我将考虑创建一个内存 SQLite 数据库,然后将该连接提供给NWRevalDatabaseEntities构造函数。但是,这似乎会慢得多(因为它会命中数据库引擎)并且单元测试应该很快,并且还需要我将数据库定义代码放入我的应用程序中,而以前不需要它。

我知道使用实体框架测试任何东西通常都会进行集成测试,而不是单元测试。但是,这些测试并没有真正测试集成 - 数据库查询非常简单,并且可能还针对数组 - 我只想检查我的方法是否正确选择了查询。

4

1 回答 1

2

有没有办法让我在我的测试类中实例化一个 NWRevalDatabaseEntities 对象而不给它一个可行的数据库连接,所以所有的表都是空的,然后只插入测试所需的实体,而不是将它们持久化到数据库中?

不。

但是,这似乎会慢得多(因为它会命中数据库引擎)并且单元测试应该很快,并且还需要我将数据库定义代码放入我的应用程序中,而以前不需要它。

但是您的方法依赖于 EF,因此您应该测试它是否可以与 EF = 和数据库一起使用。

我知道使用实体框架测试任何东西通常都会进行集成测试,而不是单元测试。但是,这些测试并没有真正测试集成 - 数据库查询非常简单,并且可能还针对数组 - 我只想检查我的方法是否正确选择了查询。

简单与否,它是一个使用 Linq-to-entities 的数据库查询。它不是使用 Linq-to-objects 的数组查询。此查询也非常简单:entities.TableOfNumbers.Last()- 它适用于数组,但不适用于 EF。如果您不想测试查询,请将其与要测试的方法分开:

public int GetNumberWithName(string name, NWRevalDatabaseEntities entities)
{
    int number = ExecuteQuery(entities, Name);
    return number;
}

现在你只需要找到如何替换ExecuteQuery测试方法。您可以制作它protected virtual并覆盖它以进行测试,因为您要测试的唯一一件事是它接收正确Name的参数并且您GetNumberWithName返回从ExecuteQuery.

现在您只需要编写集成测试ExecuteQuery来验证 Linq 查询是否与 EF 一起使用。

于 2012-09-07T09:24:33.383 回答