假设我有一个Customers表和一个具有一对多关联的Orders表(一个客户可以有多个订单)。如果我有一些我希望通过延迟加载(例如调用customer.Orders)来访问特定客户订单的单元测试的代码,我如何模拟/存根调用以便它不会访问数据库?
编辑:
为了更清楚,让我们使用一个更具体的例子。假设我想要返回特定客户的所有订单。我可以使用Linq 2 Sql提供的自动生成的延迟加载属性来编写它:
Customer customer = customerRepository.GetCustomerById(customerId);
return customer.Orders;
然而,单元测试这有点难度。我可以模拟对GetCustomerById的调用,但我不能(据我所知)模拟调用Orders。我可以想到单独测试的唯一方法是:a)连接到数据库(这会减慢我的测试并且变得脆弱)或者b)不要使用延迟加载属性。
不使用延迟加载属性,我可能会重写上面的内容:
return orderRepository.GetOrdersByCustomerId(customerId);
这绝对有效,但完全忽略延迟加载属性仅仅是为了单元测试感觉很尴尬。
答案 0 :(得分:2)
作为对你的问题的总体回答,你可以像对待其他任何内容一样来阻止这个电话。
我将假设您要进行单元测试的代码是数据访问组件的使用者,因为这是最常见的情况。如果针对接口进行编程,则只能存储数据访问权限。这意味着您必须在接口后面隐藏L2S的实现细节,以便消费代码不知道它当前正在使用哪个实现。
对此的一个证据是,延迟加载是一个实现细节,您在单元测试时不必担心,因为单元测试根本不应该使用L2S。
当删除数据访问层时,对customers.Orders
的调用通常是对Stub的内存中属性的调用。