我是针对ADO .NET实体框架编写的单元测试代码。我想用行填充内存数据库,并确保我的代码正确地检索它们。
我可以使用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?我宁愿插入一些客户行和一些订单行,然后断言选择了正确的客户并填写了订单。
答案 0 :(得分:13)
文章http://www.codeproject.com/Articles/460175/Two-strategies-for-testing-Entity-Framework-Effort描述了在内存中运行的Effort -Entity Framework提供程序。
您仍然可以在单元测试中使用DbContext或ObjectContext类,而无需拥有实际的数据库。
答案 1 :(得分:9)
这里更好的方法可能是使用Repository模式来封装您的EF代码。在测试您的服务时,您可以使用模拟或假货。在测试您的存储库时,您需要访问真正的数据库,以确保获得预期的结果。
答案 2 :(得分:7)
EF目前没有内存提供程序,但如果你看一下Highway.Data,它有一个基本的抽象接口和一个InMemoryDataContext。
答案 3 :(得分:6)
是的,至少有一个这样的提供者 - SQLite。我已经使用了它,它的工作原理。您也可以尝试SQL Server Compact。它是一个嵌入式数据库,也有EF提供商
编辑:
SQLite支持内存数据库(link1)。您所需要的只是指定一个连接字符串,如:“Data Source =:memory :; Version = 3; New = True;”。如果您在示例中需要,可以查看SharpArchitecture。
答案 4 :(得分: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);
答案 5 :(得分:1)
你可以尝试SQL Server Compact,但它有一些非常疯狂的限制:
答案 6 :(得分:0)
在EF Core中,有两个主要选项:
我正在使用SQLite,它支持我需要对Azure SQL生产数据库执行的所有查询。