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一起工作。感谢您提供了非常全面的答案!