< bean id=Helloword class=Helloworld autowire=byType> 现在看上去是不是好多了?嗯对象间的依赖关系和mock对象的创建都由 Spring 来替我们维护再也不用费心了不过reset/verify 是不是还是看上去那么舒服?我们观察一下通常为了简化对 mock 对象的验证我们对 Test 类中使用到的 mock 对象都是一起reset/replay /verify要是能有resetAll()/replayAll()/verifyAll()方法就好了也省得不同的 Test 类写一大串对不同的 Mock 对象验证的方法OK这时候我们就要借助 Reflection 来完成这项任务了通过 Reflection 得到 Test 类中所有加上 @Autowired 声明的成员变量验证它们是不是由代理或者字节码增强从而得到该 Test 类的所有由 Spring 创建的 mock 对象进行 reset/replay/verify
根据这个思路我们引入这样一个 mock 测试的Helper类
import static orgeasymockEasyMock*;
final class MockTestHelper {
public static void resetAll(Object testObject) {
reset(getDeclaredMockedFields(testObject));
}
public static void verifyAll(Object testObject) {
verify(getDeclaredMockedFields(testObject));
}
public static void replayAll(Object testObject) {
replay(getDeclaredMockedFields(testObject));
}
private static Object[] getDeclaredMockedFields(Object testObject) {
Field[] declaredFields = testObjectgetClass()getDeclaredFields();
List declaredMockedFields = new ArrayList();
for (Field field : declaredFields) {
if (fieldisAnnotationPresent(Autowiredclass)) {
boolean isAccessible = fieldisAccessible();
try {
fieldsetAccessible(true);
Object value = fieldget(testObject);
if (isClassProxy(valuegetClass())) {
declaredMockedFieldsadd(value);
}
} catch (IllegalAccessException e) {
eprintStackTrace();
}
finally {
fieldsetAccessible(isAccessible);
}
}
}
return declaredMockedFieldstoArray();
}
private static boolean isClassProxy(Class clazz) {
String className = clazzgetName();
return classNamecontains($Proxy) || classNamecontains($$EnhancerByCGLIB$$);
}
}
好了有了这么一个 Helper 类写 mock 对象的Test 类就简单了许多还是以上面的例子为例经过这么一重构变成如下
这样看起来就好多了以后不管在 Test 类里面添加多少个 Test 类需要的 mock 对象我们都不需要再修改对 mock 对象的验证了Helper类会自动< bean id=Helloword class=Helloworld autowire=byType>帮我们完成所有的工作& ltbr />综上所述使用Spring里面引入的 Test Cntext 和 annotations 的确帮助我们减轻了大量的测试代码量而且让我们的 Test 类更加POJO更易于让人理解其职责成为对 feature 的 specification而 Reflection的小技巧则能很方便的改进原来代码中不够动态的地方进一步简化代码量和维护难度当然我们可以看到即使这样代码里面还是有不少resetAll/replayAll/verifyAll的地方作为 mock 框架带来的一些约束我们没有办法来省略这里推荐一种新的 mock 框架—— mockito是有我的外国同事开发的它不仅把mockstubspy等double的概念区分更清楚而且让我们的 mock 测试更易写更易读
[] [] []