【问题标题】:Linq-SQL query logic in unit testing单元测试中的 Linq-SQL 查询逻辑
【发布时间】:2010-11-10 13:39:57
【问题描述】:
我正在尝试为我的代码编写一些单元测试。在 out 项目中,我们使用从 DBML 创建的 Linq-SQL 对象。我试图弄清楚我需要如何测试以下逻辑。
例如,我需要使用 LINQ 从表中获取记录数。
var objectCount = (from x in DB.MyRecords
where x.DateAdded.Date == DateTime.Now.Date
select x).Count(); //For example this will return 4
if(objectCount > 3)
{
//Do some logic here
}
else
{
//Do some logic here
}
现在我的理解是,如果您访问数据库,单元测试并不是真正的单元测试。
我的查询也比这更复杂,因为它的数据结构具有需要维护的外键。
现在下一个问题是,由于我们使用的是 LINQ-SQL 对象,我们没有使用接口,因此我们不能真正使用模拟框架(或者我们可以吗????)
我想知道能够对此进行单元测试的过程是什么。
【问题讨论】:
标签:
c#
unit-testing
linq-to-sql
【解决方案1】:
您需要一个介于 DBML 和业务逻辑代码之间的中间类才能进行测试。查看 Repository 模式以了解有关此的更多详细信息。
让我举一个非常简单的例子,假设你有一个 Product 表,并且你想测试你的数据库中的产品总数是否少于 10 个产品。您需要一个存储库类,以整数形式为您提供数据库中产品的数量,只要您获得数字,您就不必关心方法如何获取数字(想想抽象)。看看下面的代码sn -p:
public interface IRepository
{
int CountProduct();
}
// your implementation of repository against real database
public class DBLinqToSQLRepository : IRepository
{
// some constructor here
public int CountProduct()
{
// your code here to return the actual number of product from db.
}
}
// your implementation of fake repository that will provide fake data for testing
public class FakeRepository : IRepository
{
private List<Product> products = new List<Product>();
// some initialization here
public int CountProduct()
{
return products.Count;
}
}
然后在您的测试环境中,您可以使用这个 FakeRepository 而不是实际的数据库存储库来测试您的业务逻辑。
【解决方案2】:
您可以将此代码封装到 Repository 类中,该类可能具有以下方法,例如
public int GetNumberOfItemsAddedToday()
{
return from x in DB.MyRecords
where x.DateAdded.Date == DateTime.Now.Date
select x).Count();
}
我建议使用存储库的接口,以便您可以模拟存储库(使用类似Moq、RhinoMocks 的东西)。 This blog 帖子有一个很好的教程,介绍了如何为 LINQ To SQL 相关代码创建存储库,但网络上有很多示例以及如何执行此操作。
然后你可以对上面的代码进行单元测试
当您编写与数据库交互的单元测试时,它们往往被称为integration tests。