C# 为了单元测试的目的,实例化没有DB连接的空实体模型

C# 为了单元测试的目的,实例化没有DB连接的空实体模型,c#,unit-testing,entity-framework-4,database-connection,system.data.sqlite,C#,Unit Testing,Entity Framework 4,Database Connection,System.data.sqlite,我想为一个方法编写一些单元测试。但是,该方法引用了我的实体框架。下面是我想测试的方法的一个精心设计的示例: public int GetNumberWithName(string name, NWRevalDatabaseEntities entities) { int number = (from n in entities.TableOfNumbers where n.Name == name selec

我想为一个方法编写一些单元测试。但是,该方法引用了我的实体框架。下面是我想测试的方法的一个精心设计的示例:

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

    return number;
}
public int GetNumberWithName(string name, NWRevalDatabaseEntities entities)
{
    int number = ExecuteQuery(entities, Name);
    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();
}
//
///使用在应用程序配置文件的“NWRevalDatabaseEntities”部分中找到的连接字符串初始化新的NWRevalDatabaseEntities对象。
/// 
public NWRevalDatabaseEntities():base(“name=NWRevalDatabaseEntities”,“NWRevalDatabaseEntities”)
{
this.ContextOptions.LazyLoadingEnabled=true;
OnContextCreated();
}
/// 
///初始化新的NWRevalDatabaseEntities对象。
/// 
公共NWRevalDatabaseEntities(字符串connectionString):基(connectionString,“NWRevalDatabaseEntities”)
{
this.ContextOptions.LazyLoadingEnabled=true;
OnContextCreated();
}
/// 
///初始化新的NWRevalDatabaseEntities对象。
/// 
公共NWRevalDatabaseEntities(EntityConnection连接):基本(连接,“NWRevalDatabaseEntities”)
{
this.ContextOptions.LazyLoadingEnabled=true;
OnContextCreated();
}
所有这些都需要连接或连接字符串(或使用存储的连接字符串)

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

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

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

没有

然而,这似乎要慢得多(因为它会碰到 数据库引擎)和单元测试应该是快速的,而且 要求我将数据库定义代码输入我的应用程序, 以前不需要的地方

但您的方法依赖于EF,所以您应该测试它是否与EF=数据库一起工作

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

不管是否简单,这是一个使用Linq到实体的数据库查询。它不是使用Linq to对象的数组查询。这个查询也非常简单:
entities.TableOfNumbers.Last()
-它可以在数组上工作,但不能在EF上工作。如果不想测试查询,请将其与要测试的方法分开:

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

    return number;
}
public int GetNumberWithName(string name, NWRevalDatabaseEntities entities)
{
    int number = ExecuteQuery(entities, Name);
    return number;
}
现在您只需要找到如何替换测试的
ExecuteQuery
方法。您可以将它设置为受保护的虚拟并覆盖它进行测试,因为您要测试的唯一一件事是它接收到正确的
名称
参数,并且您的
GetNumberWithName
返回它从
ExecuteQuery
接收到的相同数字


现在您只需要为
ExecuteQuery
编写集成测试,以验证Linq查询是否与EF一起工作。

感谢您提供了非常全面的答案!