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

标签 java unit-testing testing mocking

在我学习 Java 测试的过程中,我遇到了一件我没有真正理解的事情。 所以,基本上,我有 DAO 的单元测试,我在内存数据库 HSQL 的帮助下测试 CRUD 操作。
好了,接下来就是测试Service层了。网上说用mocks模拟DAO,然后测试Service。

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

  1. 但是如果我在 Service 中有与在 DAO 中相同的方法呢?
  2. 如果我只是像使用 DAO 那样使用内存数据库来测试服务呢?

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

如果有任何意义 - 我使用 Spring。

最佳答案

这是一个广泛且可能引起争议的话题……所以请准备好接受各种各样的答案和不同的观点……

内存数据库的优势:

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

内存数据库的缺点:

  • 您的单元测试缺乏完全隔离
  • 需要为单元测试初始化​​您的 DI 容器。
  • 可能会提供错误的安全感,具体取决于内存数据库提供商与您的生产数据库的不同程度,

模拟的优点:

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

模拟的缺点:

  • 测试代码可能会变得复杂和脆弱,具体取决于服务方法的内聚程度以及它们与 DAO 层的耦合方式。即,如果您需要设置 20 个模拟方法调用和三个模拟对象,这很快就会变得乏味(但是,这应该是您的服务需要重构的标志)。

要回答您提出的第一个问题,即当您在两者中使用相同的方法时会发生什么——答案很简单。它们不是同一种方法。他们在做两件不同的事情。一个在与数据库通信,另一个在应用业务逻辑。如果您确实通过了传递,您仍然应该在服务层对其进行测试,以确保它在您的 DAO 上调用正确的东西。

无论您走哪条路,都不要忘记对您的代码进行集成测试!

关于java - 使用内存数据库和模拟测试 DAO 和服务层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53067288/

相关文章:

python - 复制/写出所有实际使用的包命令

java - Guava 事件总线 : NullPointerException when Posting from Thread to UI

java - 将 Spring Security 3.x 配置为具有多个入口点

c++ - C++ 单元测试工具的建议

c# - 当抽象类不公开每个构造函数参数时,为什么我不能创建相似代理?

android - Android 应用程序中的单元测试。我该怎么办?

angularjs - Protractor 测试后清理

.Net PetaPoco 默认查询参数

Java API 源代码

java - 从 Java (Scala) 调用 PHP 代码并获取结果