java - 单元测试和太多模拟

标签 java unit-testing

我开始在我的项目中实践 TDD,作为背景,它还包含遗留代码。我们使用 Mockito 作为模拟框架并遵循 Spring MVC 方法。

有时,Service 类使用许多不同的 DAO 对象作为 @Autowired 属性实现。这些服务中有一些简单的方法,例如 completeTransaction

completeTransaction 将使用许多 DAO 对象来完成其职责

  • 更新并保存交易
  • 推进业务流程
  • 关闭其他未决操作

但是,在执行这些操作时,该方法需要调用不同的 DAO 来获取和更新事务、获取业务流程 ID、获取挂起的事务(并保存它们的更新)。这意味着对该方法进行单元测试会让我添加许多 @Mock 属性。我需要在测试实际完成之前设置模拟对象,以便我测试特定条件。

这似乎是一种代码味道,对我来说,这几乎感觉就像是测试在确保代码的实现而不仅仅是它的契约。同样,如果不模拟依赖项,测试用例将不会运行(由于 NPE 和其他原因)。

我可以遵循什么策略来清理这样的代码? (尽管我无法真正提供有关该问题的实际源代码)。我认为一种可能性是使用(“getPendingOperations”和“advanceBusinessProcess”)之类的方法设置外观类。然后我可以模拟一个依赖项。但后来我发现,在所有其他有这种情况的类中,我需要做同样的事情,然后我害怕为了更清晰的测试而结束很多“帮助”类。

先谢谢你。

最佳答案

我认为当您发现自己有太多模拟时,通常会想做两件事。这些内容不一定简单,但您可能会发现它们很有帮助。

1) 尝试使您的方法和类更小。我认为 Clean Code 说有两条规则,即类应该小。那个类应该比那个小。这是有道理的,因为随着您测试的单元(方法和类)变小,依赖项也会变小。当然,您最终会进行更多测试,但每次测试的设置会更少。

2) 查看得墨忒耳法则 (https://en.wikipedia.org/wiki/Law_of_Demeter)。有很多规则,但基本上,您希望避免长串的属性/方法调用。 objA = objB.propertyA.SomeMethod().propertyC; 如果您需要模拟所有这些对象只是为了获得 objA,那么您将需要进行大量设置。但是,如果您可以用 objA = objB.newProperty; 替换它,那么您只需要模拟 objB 并且它是一个属性。

这些都不是 Elixir ,但希望您可以在您的项目中使用其中的一些想法。

关于java - 单元测试和太多模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21238474/

相关文章:

java - 使用tomcat可能发生内存泄漏

java - Android Intent/IntentService 的空指针异常

java - 在来自 Android 的 EWS 中将 UID 字符串转换为十六进制数组和 base64 字符串 ItemId

angularjs - Angular 单元测试中对其他服务的额外依赖

python - 成功单元测试pyinotify?

java - 塔防中寻路的最佳算法

java - keystore 加载

unit-testing - 如何编写模拟对象?

node.js - Karma 测试运行程序 - 无法捕获 chrome

ios - 在 XCTest 用例中处理 CLLocationManager 授权请求