我有以下课程:
public class LegacyClass()
{
public LegacyClass(final int aModeOfOperation)
{
if (aModeOfOperation == 0)
{
addSomeValues();
addSomeValues();
}
else if (aModeOfOperation == 1)
{
addSomeValues();
}
}
private void addSomeValues()
{
}
}
我想写一个单元测试,它会检查
LegacyClass(0)
会导致私有方法addSomeValues
被调用2次并且LegacyClass(1)
会导致私有方法addSomeValues
被调用一次。我知道可以在Mockito / PowerMockito中使用间谍对象来计算私有方法调用的数量,但AFAIK这些方法只有在有问题的方法被称为 之后才能工作。被测试的班级。
是否可以在不更改LegacyClass
的构造函数的情况下编写上述单元测试?
答案 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(); }
}
}
然后在你的测试中,你要对这个类进行内容并断言呼叫计数;