java - 在 JUnit 中设置测试的成本 - 使用模拟对象与遗留代码中的存储库测试

标签 java unit-testing junit mocking mockito

我正在从事一个已经存在多年的项目。构建包含所有测试的项目所花费的时间几乎是惊人的(不是一个好的方式)。这主要是由于大量的模块以及大量的单元测试,它们使用存储库来设置测试数据,而不是模拟所需的行为。使用存储库的单元测试需要花费大量时间来进行测试设置,并且运行速度非常慢。由于系统相当大,这会增加很多时间。

我们通过使用 Mockito 来模拟存储库来编写所有新的单元测试(除非我们实际上明显地测试存储库)。只要有时间和机会,我们还尝试重写所有现有的单元测试,以使用存储库的模拟而不是实际的存储库。在我们的测试中完全消除存储库的使用对运行测试所需的时间有巨大影响。

许多遗留代码通过使用构建器和测试实用程序来设置其测试数据,而构建器和测试实用程序又使用存储库。由于域非常复杂,这通常涉及设置相当数量的对象以及它们如何相互关联。因此,重新编写一类测试(例如约 15 个测试)以仅使用模拟对象可能会非常耗时。与其他地方一样,时间并不是无限的资源。

如果我们要向一个类添加一些新功能,那么只编写一个新的存储库测试(除了现有的 15 个测试之外)会比通过使用来准确找出测试数据需要如何设置要容易得多不同的模拟对象。

我试图找到一些关于测试设置如何以及在多大程度上影响运行测试所需的实际时间的信息,但我未能找到任何有用的信息。我唯一的“事实”是我在运行测试类时所做的观察。存储库测试的测试设置可能很容易需要约 10 秒,而模拟测试类的测试设置只需不到一秒即可开始。

注意:我知道我可以使用 JUnit Stopwatch 对单个或一组测试进行基准测试,但我的问题更关心的是最佳实践,而不是我运行测试所需的确切时间。

我有两个问题:

  1. 假设我遇到一个测试类,它已经有 15 个单元测试,其中没有一个测试模拟任何行为。我编写了一个测试并在类里面做了一个小修复。我没有时间将整个测试类重写为模拟对象。我是否应该添加一个新的测试而不模拟任何行为并遵循现有的(和坏的)模式?我有 15 个非模拟测试和 1 个模拟测试,还是有 16 个非模拟测试,这真的很重要吗?

  2. 在我的包含 15 个单元测试的测试类中,某些测试比其他测试更容易重构。仅使用模拟对象重写五个测试是否值得?拥有一个测试类,其中一些测试使用模拟,而另一些则不使用,这是否违反最佳实践或以任何其他方式不好?

最佳答案

您的问题确实很主观,但我会尝试建议您可以探索的一些选项。这完全取决于您愿意花多少钱。

Should I just add a new test without mocking any behavior and follow the existing (and bad) pattern? Does it really matter whether I have 15 non-mocked tests and 1 mocked test or if I have 16 non-mocked tests?

这不仅仅是一项新测试。如果你仍然以糟糕/缓慢的模式写作,那么你只是在增加技术债务。您必须自己制定编写新单元测试的最佳实践。

In my test class with 15 unit tests, some of the tests are easier to refactor than others. Is it worth it to re-write only five of the tests to using mocked objects?

绝对是的。为什么不?您为自己讲述了通过遵循更新的代码风格所获得的改进。

Is it against best practice or in any other way not good to have a test class where some of the tests uses mocks and some don't? Well one best practice is to have consistent code everywhere. Mix of old styled repositories and newer one with mocks does not go too well as far as best practices are concerned. But I'd be more concerned if the code you write is not well covered with unit tests, whatever style if may be.

最终,您需要做出决定并考虑所有权衡,例如通过更新的模拟存储库可以实现多少构建时间改进,构建的频率是多少,以及这是否可以通过硬件改进和其他因素来实现。

关于java - 在 JUnit 中设置测试的成本 - 使用模拟对象与遗留代码中的存储库测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50756436/

相关文章:

spring-boot - 无法在单元测试中 Autowiring 存储库(多模块 Maven 项目)

maven - Mark Jenkins 根据测试/集成测试失败构建红色/黄色

java - StringBuffer 是否与 Ruby 中的字符串相同,Symbols 是否与常规 Java 字符串相同?

Java - Set.contains() 在 OpenJDK 6 上损坏了吗?

javascript - 表达JS/jestJS : How to split get() function to write simple jest unit test?

unit-testing - 单元测试不同的标志值

java - 安装后应用程序如何打开自定义操作

java - eclipse 错误代码新手请

javascript - 在单元测试中模拟 Cordova 插件

java - File.length() 与 windows 不同,文件内容仍然相同吗?