Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中对DAOs应用单元测试_Java_Unit Testing_Dao - Fatal编程技术网

如何在java中对DAOs应用单元测试

如何在java中对DAOs应用单元测试,java,unit-testing,dao,Java,Unit Testing,Dao,我不知道如何在数据访问层上应用单元测试。我总是想知道是否应该测试数据访问层。在我的公司,我们有稳定的数据库来存储单元测试数据和测试数据访问层,通过运行数据访问对象并检查它们从稳定的数据库中获取的数据 为了通过单元测试,稳定数据库中的数据不能再修改。我认为有更好的解决办法。如果我没有弄错的话,mock对象不能对SQL语句和ResultSet映射执行测试 对DAO进行单元测试的最佳方法是什么?使用TDD有更好的方法吗?首先,根据大多数定义,“单元”测试不依赖于数据库等外部系统。您希望创建所谓的“功能

我不知道如何在数据访问层上应用单元测试。我总是想知道是否应该测试数据访问层。在我的公司,我们有稳定的数据库来存储单元测试数据和测试数据访问层,通过运行数据访问对象并检查它们从稳定的数据库中获取的数据

为了通过单元测试,稳定数据库中的数据不能再修改。我认为有更好的解决办法。如果我没有弄错的话,mock对象不能对SQL语句和
ResultSet
映射执行测试


对DAO进行单元测试的最佳方法是什么?使用TDD有更好的方法吗?

首先,根据大多数定义,“单元”测试不依赖于数据库等外部系统。您希望创建所谓的“功能”或“集成”测试。在实践中,这些类型的测试将以与单元测试相同的方式实现,使用类似Junit的东西,但是您应该将它们与单元测试分开,单元测试应该运行得非常快,并且在数据库关闭或数据更改时不会中断

第二,尝试将大部分业务逻辑排除在DAO之外,而是将其放在服务POJO层中,这样您就可以在不涉及数据库的情况下测试业务逻辑

接下来,为DAO设置测试的理想方法是从一个空数据库开始,用测试数据加载它(通常使用DAO本身),然后对已知的、可写的测试数据集运行DAO测试。如果您有幸拥有一个只读数据库,那么您概述的
稳定数据库
方法将起作用,但大多数系统都是对数据库进行读/写的


最后,测试DAOs是有价值的。通常,数据库查询是系统中最脆弱的部分,您不希望等到它们部署到生产环境中后才发现它们正在崩溃。

一些评论/建议:

  • DAO测试的目的是验证触发的查询和检索的数据是否符合预期。DAO中几乎不应该有任何要测试的业务逻辑
  • 因为主要的目标是测试数据库交互,所以mocking并不能使它变得万无一失,特别是在边缘情况下
  • 有鉴于此,你们现在所采取的方法已经足够公平了。我不知道你为什么觉得这样不好。稍微细化一下会有帮助
  • 如果您不方便使用外部数据库,那么可以使用Java的内置数据库。请注意,在运行此测试之前,首先创建测试数据会带来开销
    严格地说,您正在编写一个功能测试。要做到这一点,您需要一个这样或那样的测试数据库。让我们谈谈你的选择

  • HSQL/内存中数据库。又小又快。设置和运行起来很简单,而且在单元测试大小的数据上性能很好。缺点是,除非您使用这些环境进行部署,否则您可能会面临单元测试工作失败的风险。这还意味着您不能使用任何在HSQL和生产数据库中都不支持的SQL构造。这可以通过使用Hibernate或类似的方法在一定程度上缓解。如果您只有非常简单的查询,那么这是一个很好的方法

  • 完全模拟数据库调用。没有意义,除非你在你的刀上做了太多的繁重工作

  • 使用生产数据库的测试实例。这将为您提供准确度或结果方面的最佳结果。它将允许您进行测试,以确保所有调用都按预期工作,并允许您使用不可移植的SQL。您可以使用DBUnit之类的工具来加载数据库数据,也可以使用被测DAO来加载数据库数据。如果你有大而讨厌的疑问,我建议你这样做。有很多边缘案例、卷起视图和微妙行为的。缺点是真正的DBs将招致性能损失,因为它们将进行真正的工作(事务、索引更新、回滚支持)


  • 对于基于JDBC的项目,可以模拟JDBC连接,这样就可以在没有实时RDBMS的情况下执行测试,并隔离每个测试用例(无数据冲突)

    它允许验证、持久性代码传递正确的查询/参数(例如),并按预期处理JDBC结果(解析/映射)


    像jOOQ或myframeworkacolyte这样的框架可以用于:。

    您可以试试DBUnit。它允许您创建数据集,以便您的测试用例可以在这些数据集上运行。在执行测试之前,可以将数据集中的测试数据初始化到数据库中。这将允许您获得可重复的测试结果和“稳定”的数据库。IMHO,这不好,因为OP要求进行单元测试。他/她的设置不是单元测试。那么,单元测试在DAO中可能没有任何用途。测试代码的唯一自动化测试是OP已经在做的事情。不是真的。为了对业务逻辑进行单元测试,她/他可以使用DBUnit,这在另一个答案中提到过。针对真实数据库的“单元测试”不是单元测试。按照同样的逻辑,我们可以说单元测试通常没有任何用途,因为任何问题都会在功能测试或集成测试期间被检测到。许多人将“单元测试”称为任何形式的自动化测试,尤其是功能测试和集成测试。这是不对的。单元测试、组件测试、功能测试和集成测试都可以手动或自动进行。这一点很好。事实上,包含任何形式的业务逻辑的DAO都不是DAO:它是一团乱:-)