[英]How do I unit test overridden methods which call super?
http://stackoverflow.com/questions/6645263/unit-testing-overridden-methods-which-call-super(这个问题有类似的措辞,但不一样)
我有类似的东西:
public class SuperClass {
private int superClassInteger = 2;
public void superClassMethod() {
superClassInteger = 5;
}
public int getSuperClassInteger() {
return superClassInteger();
}
}
然后在我的测试中我有:
public class SuperClassTest {
public void testSuperClassMethod() {
SuperClass superClass = new SuperClass();
superClass.superClassMethod();
assertEquals(5, super.getSuperClassInteger())
}
}
然后我有一个子类:
public class SubClass {
private int subClassInteger = 2;
public void subClassMethod() {
super.superClassMethod();
subClassInteger = 32;
}
public int getSuperClassInteger() {
subClassInteger;
}
}
然后我测试子类:
public class SubClassTest {
public void testSubClassMethod() {
SubClass subClass = new SubClass();
subClass.subClassMethod();
assertEquals(5, subclass.getSuperClassInteger());
assertEquals(32, subclass.getSubClassInteger())
}
}
我的问题是,为了测试子类的行为,我正在重复我对超类的测试代码。 我可以拿出: assertEquals(5, subclass.getSuperClassInteger());
因为我只想测试子类的业务逻辑。 但是,问题是如果有人意外删除了对superClassMethod
的调用,测试仍会通过。 所以我需要验证对super的调用。 测试此用例的常用方法是什么?
注意:我知道组合/策略模式与继承有助于解决这个问题,但为了解决这个问题,你基本上说我不应该覆盖一个方法并在我的代码中调用super(我很难相信它永远不会有用于)
使用mockito间谍。 您可以使用该测试框架检查几乎任何方法调用。
这可能不是你想要的答案(即不是解决方法),
而是你应得的答案,
但你永远不应该重写方法并调用super。
我正在研究一个遗留项目,它做了很多,维护,调试和测试都是一场噩梦。
相反,最好使用带有模板方法模式的抽象类:
public class SuperClass<T> {
public void include(T t) {
validate(T);
dao.save(T);
}
// I've found code like that.
public void validate(T t) {
}
}
public class SubClass1 extends SuperClass<MyClass> {
@Override
public void include(MyClass mc) {
doStuff(mc);
doMoreStuff(mc);
super.include(mc);
}
@Override
public void validate(MyClass mc) {
doValidationStuff();
}
}
public class SubClass2 extends SuperClass<AnotherClass> {
@Override
public void include(AnotherClass ac) {
doDifferentStuff();
super.include(mc);
}
}
public abstract class AbstractClass<T> {
abstract void validate(T t);
// this method can now be tested
public void include(T t) {
validate(T);
dao.save(T);
}
}
public class Class1 extends AbstractClass<MyClass> {
public void validate(MyClass mc) {
doValidationStuff();
doStuff(mc);
doMoreStuff(mc);
}
}
public class Class2 extends AbstractClass<AnotherClass> {
public void validate(AnotherClass ac) {
doDifferentStuff();
}
}
正如您所看到的,这种重构简化了维护和测试,您不必担心必须在Class1和Class2测试中模拟超类方法调用,并且代码关闭以修改并打开扩展,即更易于维护。
使用JMockit并通过验证检查对super的调用。
这方面的例子
public void test {
SubClass subClass = new SubClass();
subClass.subClassMethod();
new Verifications() {
// mock only this method of superClass - and only in this test
@Mocked (methods = "superClassMethod")
SuperClass superClass;
{
superClass.superClassMethod();
times = 1; // specify invocation count
}
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.