少于100%的分支机构覆盖率单元测试。该如何解决?

时间:2018-10-25 22:40:04

标签: java fibonacci

我有一个记忆式递归函数来计算斐波那契数。我有此功能的测试用例。基本上,它发送一个位置,如果该位置已经有一个数字,则将其返回,如果没有,则进行计算。我通过调试器运行了代码,并意识到:

if (dictionary[position] != null){
    result = dictionary[position];
  }

从未被击中。完整代码如下。例如,如果您有calculatefib(4),它将要求fib(3),要求fib(2),要求fib(1),要求fib(0),以及何时堆栈开始关闭,永远不会保存值。因此,例如fib(2)或更确切地说dictionary(2)始终为null。它在调试器中的令人困惑的原因是它显示了计算出的值,但是当堆栈开始关闭时,它们又再次为空。我如何重构代码,使行始终被点击。

public BigInteger calculateFib(int position) {

final BigInteger[] dictionary = new BigInteger[100000];

BigInteger result = BigInteger.ONE;

if (position < 2) {
  return result;
}
else {
  if (dictionary[position] != null){
    result = dictionary[position];
  }
  else {
    result = calculateFib(position - 1).add(calculateFib(position - 2));
    dictionary[position] = result;
  }
  return result

4 个答案:

答案 0 :(得分:0)

每次您致电calculateFib()此行:

final BigInteger[] dictionary = new BigInteger[100000];

创建数组dictionary[]的临时实例
calculateFib()完成后,dictionary[]被销毁。
如果要在其中存储值并重用它,则必须在calculateFib()之外的类级别上声明它。
编辑,这是我对您的逻辑的看法:

final BigInteger[] dictionary = new BigInteger[100000];

public BigInteger calculateFib(int position) {
    if (position < 0)
        return BigInteger.ZERO;

    BigInteger result = BigInteger.ONE;


    if (dictionary[position] != null) {
        result = dictionary[position];
    } else if (position < 2) {
        dictionary[position] = result;
    } else {
        result = calculateFib(position - 1).add(calculateFib(position - 2));
        dictionary[position] = result;
    }

    return result;
}

答案 1 :(得分:0)

您应该在方法外部声明备忘录存储,因为它必须记住方法调用之间的内容。现在,您正在为每个方法调用创建一个新的“ memo”存储字典,因此您永远不会记住任何东西。

将此方法带到类实例之外:

final BigInteger[] dictionary = new BigInteger[100000];

class MyClass {
    final BigInteger[] dictionary = new BigInteger[100000];

    public BigInteger calculateFib(int position) {      
        BigInteger result = BigInteger.ONE;

        if (position < 2) {
          return result;
        }
        else {
          if (dictionary[position] != null){
            result = dictionary[position];
          }
          else {
            result = calculateFib(position - 1).add(calculateFib(position - 2));
            dictionary[position] = result;
          }
          return result
        }
    }
}

答案 2 :(得分:0)

memoize不会达到您期望的结果。 每次调用方法都需要初始化一个新字典,该字典将在该方法完成时终止。

您需要提取字典变量并将其初始化为方法之外。

final BigInteger[] dictionary = new BigInteger[100000];

答案 3 :(得分:0)

如果将dictionary移动到方法之外,您的代码将显示100%的覆盖率

这里有一张照片可以证明这一点:

enter image description here

但是,如果我生成“覆盖率报告”,则会显示75%的方法覆盖率:

enter image description here

此报告显然是不正确的,因为它显示了每个方法和每一行都被命中,并且在IDE中显示了100%的方法覆盖率,所以我会说此处的覆盖率工具有误 。您可能要报告错误。