读书人

运用反射提高单元测试的质量

发布时间: 2012-07-01 13:15:00 作者: rapoo

使用反射提高单元测试的质量
首先,单元测试以及单元测试覆盖率只是一个工具,很烂的代码一样可以有全套的单元测试和很高的单元测试覆盖率(这里只指代码覆盖率,不涉及分支覆盖等)。其次,单元测试和覆盖率是有用的,尤其是在我们想把一件事情搞好的时候。

单元测试顾名思义就是对单元进行测试,这里的单元就是方法。但是我们在类的设计中会设计方法的访问限定符,以此来更好的做到高内聚,低耦合。如果只是对public的方法做测试,那么为了验证一些private方法的正确性,我们就需要以public方法为入口,构造复杂的测试上下文,如此,增大开发测试的负担。那么,对不公开的方法如何测试呢。

1 采用java独特的包访问权限,这样的话,product code和test code可以放在不同的目录,但是可以有相同的包名。这样的缺点是test影响了product code的设计。

2 采用反射,采用反射可以访问product code的private方法,这样,test和product就完全隔离开了。这样的缺点是test中对方法名要进行hard code,不利于重构。但是权衡利弊,这个方法还是可行的。

在用反射做UT时,注意,使用的是getDeclaredMethod方法而不是getMethod,同时注意使用method.setAccessible(true)来使方法可以被访问。在实现的时候,最好有一个方法的转调,以减少代码重构对test的影响(这样只有一个地方hard code)。

比如我们有一个

private int getUserAge(String userId) 的方法,为了测试,在test中可以有如下结构。

//调用指定对象的指定方法。用java的反射机制实现。
private Object invokeMethod(String methodName, Class<?>[] parameterClasses, Object object,
Object[] parameters)

//转发调用。
private int invokeGetUserAge(String userId){
调用invokeMethod,做适当的类型转换。
}

//真正的test方法,调用invokeGetUserAge。
public void testGetUserAge()


#ifdef _MY_TEST#define private public #endif
爽吧?

读书人网 >软件开发

热点推荐