【问题标题】:Testing Linq Queries EF and the Repository Pattern测试 Linq 查询 EF 和存储库模式
【发布时间】:2013-02-15 04:45:47
【问题描述】:

相信我,我已经阅读了很多关于 SO 的文章和问题。但我还没有找到满意的答案。 以Matt Robert's Tutorial上的repository模式和单元测试为例:

我不明白.. 两个存储库是否包含完全相同的查询逻辑?似乎是这样,如果是这样,那是一个有用的模式吗?这意味着每当我更改假存储库中的查询时,我都必须更改实际存储库中的查询逻辑——这听起来像是 PITA 和问题的配方。

我想将查询保留在 one 方法中并测试该方法。后来我想到,我可以这样做:

//Student can be from the db or a fake list
public person GetStudent(IEnumerable<Student> students,int studentid)
{
   return students.FirstOrDefault(s =>s.PersonId ==studentid);
}

//unit test
    Assert.IsNull(GetStudent(fakeStudentList, -1))
//actual code
    var student =  GetStudent(entities.students,-1) 

有没有模仿上面的模式?如果是这样,它是什么?或者这实际上是存储库模式的工作原理?如果是这样,为什么感觉存储库模式重复了代码?

还有,努力..看看这可怕的example:S?

【问题讨论】:

  • 好问题和好用户名(等不及第 13 本书了!)。 +1
  • @Brian 这本书已经出版了:P
  • 呃...我的意思是第 14 本书,我看到 也已经出版了!
  • @Brian Yep,不幸的是,我正在与设计模式和测试作斗争以开始阅读:(但很快:P
  • 我要说的是为你的存储库编写一个单元测试,然后将上下文最小化。然后我读了这个答案并意识到它并不那么简单 - stackoverflow.com/a/1894066/201648。但是,我认为该答案中的链接可能对您有用。

标签: c# entity-framework unit-testing repository-pattern


【解决方案1】:

没有什么可做的,但我认为您的存储库模式存在缺陷。

您不应将学生收藏传递给GetStudent()GetStudent 应该是一个内部知道学生列表的类的一部分 - 无论是文件、List、数据库,等等。

所以你的“假”存储库可能具有相同的逻辑,或者它可能只是返回一个硬编码的虚拟Student。如果您伪造存储库,我认为是因为您正在测试需要存储库的其他东西,所以它不应该关心它是如何获得Student

您引用的文章也只提到了一个存储库,所以我不确定您为什么需要复制它。

【讨论】:

  • 如果GetStudent() 知道Student list 或某些数据结构,我认为这是糟糕的设计。学生列表来自哪里无关紧要 - 我应该能够测试一次查询。关于这篇文章,那是因为不幸的是我找不到他们实现两个存储库的示例。但是实现存储库会产生重复的想法,但我仍在搜索。
  • 它必须了解底层集合。这才是重点。您可以以某种方式初始化存储库,为它提供底层数据,但它知道它。有一个存储库方法有什么意义,你交给一组学生并要求它“给我一个 ID 为 x 的”?为什么不自己做呢?存储库的重点是抽象出底层集合。
  • StudentRepository 类了解数据库/存储库的设计有多糟糕?否则,StudentRepository 类的意义何在?
  • 这样想——你不测试假货——你创造用于测试其他东西的假货。
  • 存储库在内部做什么并不重要,您将测试它的接口,它的外部合同。如果您需要一个假的、模拟的存储库,您不必实际编写复杂的查询,因为您正在伪造结果。当然,您可以拥有在内部执行复杂操作的存储库。
猜你喜欢
  • 2011-09-04
  • 1970-01-01
  • 2012-02-08
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多