繁体   English   中英

为单元测试目的实例化没有数据库连接的空实体模型

[英]Instantiating an empty Entity Model without a DB connection for Unit Testing purposes

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

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构造函数。 但是,这似乎会慢得多(因为它会影响数据库引擎)并且单元测试应该很快,并且还需要我将数据库定义代码放入我的应用程序中,以前不需要它。

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

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

没有。

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

但是你的方法依赖于EF,所以你应该测试它与EF = with database一起工作。

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

简单与否,它是使用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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM