繁体   English   中英

使用内存数据库和模拟测试DAO和服务层

[英]Testing DAO and Service layer with in-memory db and mocking

在学习Java测试的过程中,我遇到了一个我没有真正得到的东西。 因此,基本上,我有针对DAO的单元测试,其中我借助内存数据库HSQL测试了CRUD操作。
好了,下一步是测试服务层。 在网络上,他们说要使用模拟来模拟DAO,然后测试Service。

我只看到一种使用模拟的方法:如果Service中有某些方法,而DAO中不存在这些方法。 然后,我们不需要测试CRUD操作(DAO本身),因此我们模拟DAO并仅测试Service。

  1. 但是,如果我在Service中使用与DAO中相同的方法怎么办?
  2. 如果我像使用DAO一样仅使用内存数据库来测试Service,该怎么办?

我想知道什么是使用模拟考试 ,而不是一个内存数据库的好处。 而且,我猜想,使用Mocks时可读性较差。

如果有意义的话-我使用Spring。

这是一个广泛且可能引起争议的主题……因此请准备好应对各种各样的答案和不同的观点……

内存数据库的优点:

  • 可能会减少一组集成测试,这些集成测试旨在确保您避免延迟/明确的加载情况,并确保获得格式正确的实体。
  • 在某些情况下,它可能会减少每种测试方法所需的设置代码。 例如,如果您必须在几个不同的模拟上建立一打模拟调用。
  • 在了解要测试的内容时,有时可以更容易地对测试进行推理

内存数据库的缺点:

  • 缺乏针对单元测试的完全隔离
  • 需要对您的DI容器进行初始化以进行单元测试。
  • 根据内存数据库提供程序与生产数据库的不同程度,可能会提供错误的安全感,

模拟的优点:

  • 完全隔离正在测试的代码
  • 可以设置支持您的测试所需的一切。 例如,不需要配置完整的实体。
  • 测试通常运行得更快,您可以完全忽略用于单元测试的DI框架(隔离的一部分,但值得一提)。

嘲讽的缺点:

  • 测试代码可能变得复杂而脆弱,这取决于服务方法的凝聚力以及它们与DAO层的耦合方式。 也就是说,如果您需要设置20个模拟方法调用和3个模拟对象,那很快就会变得乏味(但是,这应该表明您的服务需要重构)。

要回答第一个问题,您问到两种方法都相同时会发生什么—简单答案。 它们不是相同的方法。 他们在做两件事。 一个正在与数据库进行通信,另一个正在应用业务逻辑。 如果确实有传递,则您可能仍应该在服务层中对其进行测试,以确保传递的是您DAO上正确的信息。

无论您采用哪种方式,都不要忘记对代码进行集成测试!

从经验(已经编写了成千上万的自动化测试)中讲:

  1. 尽可能避免进行模拟,因为这不利于进行正确的测试。 通常,使用模拟的测试是从错误的角度编写的,即开发人员仅考虑执行实现代码,而不是检查有意义的面向业务的行为。 好的测试是根据需求编写的,而不仅仅是为了执行代码。

  2. 集成测试可以足够快(真正重要的是开发人员不要被劝阻不要经常运行它们),并且可以使它们在仅回滚的DB事务中运行,从而确保测试隔离。

  3. 使用开发数据库(通常是使用与生产环境相同的数据库引擎的共享远程数据库,在该数据库中也可以手动测试应用程序),而不要使用内存数据库。 这样,您可以避免在每次测试运行时都创建昂贵的内存数据库模式(假设通常情况下,开发数据库始终处于运行状态,并且具有所有表),并且避免了由于使用两种不同的数据库技术而引起的任何潜在问题。

上面描述了我在Java Web应用程序中使用的方法(使用Java EE或Spring没关系),该数据库在关系数据库中具有数百个表(可通过JPA / Hibernate访问)。 容器外集成测试只有一个测试套件,其中每个测试都在单个db事务中运行,并且始终回滚。 一些测试做了一些模拟,特别是对于远程Web服务的调用,仅此而已。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM