如何验证构造函数中的私有方法调用数?

时间:2013-11-27 11:39:35

标签: java unit-testing mocking mockito powermock

我有以下课程:

public class LegacyClass()
{
    public LegacyClass(final int aModeOfOperation)
    {
        if (aModeOfOperation == 0)
        {
            addSomeValues();
            addSomeValues();
        }
        else if (aModeOfOperation == 1)
        {
            addSomeValues();
        }
    }

    private void addSomeValues()
    {
    }
}

我想写一个单元测试,它会检查

  1. 调用LegacyClass(0)会导致私有方法addSomeValues被调用2次并且
  2. 调用LegacyClass(1)会导致私有方法addSomeValues被调用一次。
  3. 我知道可以在Mockito / PowerMockito中使用间谍对象来计算私有方法调用的数量,但AFAIK这些方法只有在有问题的方法被称为 之后才能工作。被测试的班级。

    是否可以在不更改LegacyClass的构造函数的情况下编写上述单元测试?

2 个答案:

答案 0 :(得分:4)

如果您可以对公共方法的要求/行为执行基于状态的测试(http://blog.jayfields.com/2008/02/state-based-testing.html?m=1)而不是测试私有方法的调用次数,我认为您可以从单元测试中获得更好的价值。这在某些隔离框架中可能是可能的,但从单元测试的角度来看,我没有看到太多价值。

考虑一些单元测试,你会验证一个方法已被调用,或者一个方法被称为x数字,如果次数。这些测试是验证测试,它们仍然有效。但关键因素是大多数模拟对象框架允许您对公共方法(至少在.net中)进行这些验证。原因是私有方法从单元测试的角度来看并不重要,因为它们的内部实现细节。尽量避免代码原理图更改的测试失败。

答案 1 :(得分:1)

我不认为使用mockito是可能的,因为你以这种方式spy(new LegacyClass())声明了间谍,因此你的构造函数在对象被窥探之前被调用。也许有一种使用PoweverMock的方法,但我通常不鼓励使用PowerMock,因为没有努力将重构代码放到适当的设计中。

相反,我强烈建议您将旧版代码重构为更可测试的代码(测试驱动开发是他的关键)。

如果你绝对需要保留这些遗留代码兼容的更改,但没有PowerMock;我首先会将可见性级别提高到包可见

private void addSomeValues() { ... }

然后在测试中编写LegacyClass的静态子类,并覆盖addSomeValues方法,该方法将增加一个计数器超级调用。

public class LegacyCodeTest {
  ...

  static class AddSomeValuesCounteringLegacyClass extends LegacyClass {
    public int counter;
    void addSomeValues() { counter = counter + 1; super.addSomeValues(); }
  }
}

然后在你的测试中,你要对这个类进行内容并断言呼叫计数;