首页 > 解决方案 > 如何模拟尾递归函数?

问题描述

我想测试我的代码,它有一些尾递归函数。我无法模拟尾递归函数,因为它们需要声明Finalor Private。大多数模拟框架不支持模拟此类方法,支持的方法无法按预期工作。

这可能吗?有人可以提供他们的想法来模拟尾递归函数吗?

我尝试使用MockitoFramework version进行模拟3.0.0。我的测试套件扩展了Mockito-Sugartrait。

尽管 mockito文档表明可以模拟 final 方法,但它会导致我失败。

我尝试使用scala-mock. 我遇到了不同的问题,但没有解决。

标签: scalamockingmockitopowermockscalamock

解决方案


解决此问题的一种方法是将递归代码包装在外部函数中。例如:

def factorial(n: Int): Int = {
  @annotation.tailrec
  def loop(i: Int, res: Int): Int =
    if (i <= 1) {
      res
    } else {
      loop(i-1, i*res)
    }

  loop(n-1, n)
}

使用这种模式,该factorial方法不需要final或者private可以被覆盖以进行测试。

这种模式的另一个优点是累加器值res不必暴露在主函数接口中。这种模式还允许在主递归代码之外处理特殊情况,从而使内部代码更简单并且可能更快。


推荐阅读