【问题标题】:DAO Unit testingDAO Unit testing
【发布时间】:2012-04-06 03:16:59
【问题描述】:

我一直在查看 EasyMock 以及将其用于单元测试 DAO 类的教程/示例,用于“外部容器”测试。但是,我认为他们中的大多数人都在谈论测试服务层,而是模拟 DAO 类。我有点迷茫,你真的是这样对DAO层进行单元测试的吗?

有些人会说与 DB 和 EJB 交互的测试实际上是集成测试,而不是单元测试,但是您如何知道您的 SQL 是否正确(假设没有 ORM)以及您的 DAO 从您的真实数据中插入/查询正确的数据(读取,类似于生产中的本地数据库)数据库?

我读到 DBUnit 是针对这种情况的解决方案。但我的问题是关于使用像 DBUnit “外部容器”这样的框架。如果 DAO 依赖于某些 EJB 会怎样,我们如何处理事务,如果有触发器更新插入时的其他表会发生什么?

仅对具有此类依赖关系的 DAO 进行单元测试的最佳方法是什么?

【问题讨论】:

  • 我认为测试 DAO 方法不是一个好主意,因为在这种情况下,您正在测试查询和底层 ORM 框架(如果您使用的话)。我阅读了其他人的 cmets,我看到许多人提供了针对 DAO 方法执行单元测试并在这种情况下使用内存数据库的建议。我不知道他们是否试图实现这一点,但这里的问题是不同的数据库在某些情况下会导致不同的语法,并且不要告诉我 ORM 层可以让你摆脱这种情况,它可以,但你的测试仍然不一致你对不同的数据库执行它们。
  • (...continue of previous comment) 那么,不一致的测试有什么意义呢?这种测试不会测试任何东西,并且会让您对使用主题测试的功能的正确性产生扭曲的看法。同时它给项目带来了很多问题。

标签: unit-testing dao easymock dbunit


【解决方案1】:

就我个人而言,我通过访问某种测试数据库来对 DAO 进行单元测试,最好是与您的应用在生产中使用的相同类型的数据库(显然不是相同的数据库)。

我认为如果你这样做,测试更像是一个集成测试,因为它依赖于正在运行的数据库。这种方法的好处在于它尽可能接近您正在运行的生产环境。它的缺点是您需要测试配置,您需要一个正在运行的测试数据库(在您的机器本地或环境中的某个地方),并且测试可能需要更长的时间才能运行。您还需要确保在测试执行后回滚测试数据。

一旦 DAO 经过测试,一定要模拟它们以对您的服务进行单元测试。

【讨论】:

  • 那不是集成测试吗?
【解决方案2】:

通常使用 DAO 的想法是对数据访问代码进行最小的包装,因此除了映射到数据库之外没有什么可以测试的,使用模拟的单元测试是无用的。如果 DAO 中确实存在值得用 mock 测试的逻辑,那么可能会认为您在滥用 DAO 模式并且该逻辑应该在服务中。

对于测试到数据库的映射DBUnit 很有用,因为它允许您在测试之前指定起始数据集,以便您的测试从已知状态开始,并且它允许您指定数据的结束状态应该是什么是,所以你不必编写大量的单元测试代码来断言什么是预期的。

理想情况下,如果您有一个像 Hibernate 这样的工具可以将数据库抽象出来,您可以使用 H2 或 HSQLDB 等内存数据库,这样您的测试运行得更快,并且无需创建数据库。如果您必须使用真正的数据库,请确保您的测试自己拥有它,以便他们可以创建和删除数据,而不会影响或受其他进程影响。在实践中,无论是在本地还是在 CI 环境中,都不太可能拥有自己的数据库,而使用内存数据库更为实用。

【讨论】:

    【解决方案3】:

    作为对 Koya anwers 的补充,您可以使用 HSQLDB 进行 DAO 测试。我想你在你的项目中使用了 Spring 和 Hibernate。您需要单独的配置文件来指向 HSQLDB,您需要在执行测试之前插入数据。使用 HSQLDB 可以做的事情有一些限制,但一般用作查询和连接是可以的。有了这个解决方案,就可以在一个连续的环境中使用,比如jenkins。 集成测试可以使用 HSQLDB ,所以这部分没有被模拟。

    【讨论】:

      【解决方案4】:

      我正在使用 HSQLDB 进行 Dao 和服务 API 测试。性能很好,它也支持事务。我没有使用 EJB。我使用休眠。

      据我所知,在不同的数据库上运行测试可能会掩盖一些受支持的数据库问题。但我认为这些问题应该在冒烟和验收测试中发现。

      问候, 高野

      【讨论】:

        【解决方案5】:

        我最终决定编写可以在容器外运行的单元测试,使用动态数据库和使用独立事务管理器 (Bitronix) 的事务支持,我也能够回滚。我想这不会使测试仍然是纯单元测试......很想听听大家对这种方法的意见。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-02
          • 2020-04-25
          • 2021-12-15
          • 1970-01-01
          • 2017-11-09
          相关资源
          最近更新 更多