上周末去听了Scrumgathering的试讲活动,感觉此类活动还是挺有意思的,一群scrum实践者或者爱好敏捷的同学在一起讨论如何做好敏捷项目,这次主要听了一场关于如何对遗留代码做单元测试的演讲,因此向记录一下一些很好的观点,来用于我们对单元测试的理解,以及如何提高代码可测性。
所谓的遗留代码(legacy code),简单就是指没有任何测试的代码。那么我们如何来对这些遗留代码进行测试,或者是通过修改使这些遗留代码能够变的更加testability。
案例一
public class Car{ private Engine engine; public Car(){ engine = new Engine(10); } public boolean isMove(){ return engine.speed()>0? true:false; } } |
针对这个class的test case应该是这样的:
public class TestCase{ private Car car; public void testMove(){ car = new Car(); Assert.assertEquals(true,car.isMove()); } } |
对于这个测试用列,我们并没有真正的达到测试Car的isMove方法的正确性,因为Car在这里对Engine类的一个依赖,在这个测试用列中我们没法达到测试isMove方法中的逻辑。因此我们需要对Car这段遗留代码进行解依赖。
对Car这个类的构造函数进行修改
public class Car{ private Engine engine; public Car(Engine engine){ this.engine = engine; } public boolean isMove(){ return engine.speed()>0?true:false; } } |
测试代码如下:
public class TestCase{ public Car car; public void testIsMove(){ Engine engine = new MockEngine(10); car = new Car(engine); Assert.assertEquals(true,car.isMove()); } } |
可以看到这时的测试代码已经完完全全的在测试isMove方法了,我们不需要关心Engine,我们可以随便mock一个engine对象。这样就完成了对Engine的解依赖,使代码具有可测性。
案例二
提高方法的可见性,如果实际工作中我们需要对一个private的方法进行测试的话,我们可能会无从下手,对于这类测试,我们可以说是该方法无法在测试工具中导入,那么这个时候,我们需要提升一下方法的权限,比如我们可以将private方法改为protected,那么我们就可以通过子类继承被测类,子类中对protected方法是可见的,那么我们就可以将子类导入到测试用具中完成测试工作。