.net - .NET 存储库本身通常不被测试?

  显示原文与译文双语对照的内容
122 3

很抱歉,我是新的知识库模式,单元测试和orm工具的新手。

我一直在研究单元测试和知识库 Pattern,并得出一些结论,我想知道我是否正确。

repository Pattern 便于在控制器中替换单元测试,例如在控制器中使用它,例如?因为创建上下文( 有效) 或者会话( 在NH中)的存根/假是困难的,对?存储库本身未被测试?为什么?

如果我想测试存储库,使用EntityFramework或者 NHibernate 来测试存储库,我需要做集成测试?因为如果我使用我的上下文/会话的假实现,我不做真正的测试?因为上下文/会话本身是存储库( 他们实现了添加。删除。编辑。GetById 。GetAll的真正逻辑。)?

使用EF或者NH的存储库 Pattern 就像一个包装器?( 我知道这不仅仅是包装器,我知道这是域的导入概念。

时间:原作者:0个回答

99 2

在这种情况下,我将严格不同于 in,并且我不会在同一问题中包含这两种技术。简单的NH更成熟,并且具有更易于测试的代码。如果在数据库中添加数据库,它也可以在 switch 中运行,但在切换数据库的情况下,它仍然是相同的,如果你在MS和非MS数据库之间进行 switch 测试,那么这是不需要的。

什么是知识库让我们看看 的Martin定义:?

存储库与域和数据映射层协调,类似于内存域对象集合。客户端对象以声明方式构造查询规范,并将它们提交到存储库以满足需求。可以以从存储库中添加和删除对象,因为它们可以以从一个简单的对象集合中执行。从概念上讲,存储库封装了存储在数据存储中的对象集,并提供了一个面向对象的视图。Repository还支持实现干净分离的目标,以及在域和数据映射层之间实现单向依赖的。

好定义。现在考虑 DbSet的用途:

  • 它在内存收集中是否起作用?是,可以使用它从数据库获取实体,或者使用 Local 属性来获取已经加载的实体。
  • 客户端是否可以以声明方式查询规格?是的,叫做 linq-to-entities 。
  • 可以从集合中添加或者移除对象?是可以。
  • 映射是否封装是的。
  • 是否有干净的分离是的,逻辑是。就API而言,因为公开 IDbSet 将使领域模型依赖于技术- 有效。是否有问题理论上是,purist purist purist 99%因为当你需要改变 API rare API API API API API 。

DbSet 是一个存储库。直接使用 DbSet 和将它的包装到一些通用存储库之间的惟一区别是分离。这导致我以前对类似问题的回答- 通用库带有 EF 4.1,这是什么

现在,应用程序中存储库的用途是什么?你以前的问题包括这个问题,你在上面建立了你的BaseRepositoryif,seriously,seriously,Pattern,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing,exposing 。但是,如果只包装上下文和单一集,并调用这个存储库,则可以能只创建了冗余层。

在这种情况下,你的知识库( DbSet 包装器) 仅有一种特殊情况:

  • 包装器永远不会公开 IQueryable ( linq-to-entities )
  • 包装器永远不会接受 Expression<> 并将它的传递到 IQueryalbe ( linq-to-entities )

这是唯一能提供你完全的mockable仓库=>的场景upper你的可以很容易的被测试。你不会去 单元测试 仓库,也不会去模拟仓库中使用的上下文。存储库封装数据访问和映射逻辑- 在存储库中唯一合理的测试是集成测试。这个场景的问题是什么?你将失去LINQ的全部功能,你将必须包装/重新实现实现in的某些方法和类型。这种存储库与使用存储过程包装数据访问时使用的存储库相同。

如果你不遵循那个场景你的生活会更容易。你将有一个由LINQ定义的查询,但是你将无法使用 单元测试,因为没有模拟/假的查询。模拟 DbSet 或者 IQueryable 之后,你将使用 linq-to-object,它是linq-to-entities的。你可以轻松编写一个查询,它将通过模拟的DbSet 传递一个测试,但在运行时使用真正的DbSet 失败。下面是关于这个问题的更多信息,这里是 ,它是通过测试但在运行时失败的查询示例。在这种情况下,你必须使用集成测试( 使用真实数据库),在你的存储库之上使用linq-to-entities查询进行所有方法。

原作者:
124 0

储存库接口属于域层。但是实现属于基础设施或者数据访问层。这里实现通常不使用单元测试进行测试。它大量使用 ORM API,因此隔离存储库是非常困难和浪费的。这里问题不是特定于仓库的:不模拟你不属于的类型。

存储库应该用的集成测试来测试,使用真正的ORM 。在内存中,数据库是一种非常流行的面向对象的方法,用于这个问题。

"。"。因为如果我使用上下文/会话的假实现,我不会做实际测试?

即使你把它变成 NHibernate的( 我非常怀疑) 你也会浪费你的时间。会话/上下文界面超出你的控制权,你的测试只会重复你对真实事件的猜测。

因为上下文/会话本身就是存储库?

否。上下文/会话是 UnitOfWork Pattern的实现。这不是你的领地的一部分。这是基础设施。

带有EF或者NH的储存库 Pattern 只是一个包装器?

存储库是重要的领域概念,它不仅仅是一个'包装器'。就像你的应用程序不是数据库上的'包装器'一样。我认为,基于的存储库界面定义应该尽可以能多地基于语言,不应该包含任何ORM相关的词。

原作者:
106 4

制作数据库只是数据库访问的轻量级包装器,并将业务方法放在实体服务层中是很常见的。因此,你可以使用包装。比如 。内存数据库中的存储库来 单元测试 实体服务。

原作者:
...