在测试的过程中, 会用到一些模拟数据, 希望在每次调用测试方法之间对这些数据进行一下初始化,类似@Before注解的方法, 在调用测试方法之间被调用一次, 我希望通过注解来做这件事儿.于是有了下面的做法:
通过阅读JUnit4ClassRunner源代码, 发现在createTest()方法中做这件事比较合适:
参照查找@Before 注解的方法的代码, 查找所有带@FieldBefore的方法:
最后是@FieldBefore的定义:
用法如下:
通过阅读JUnit4ClassRunner源代码, 发现在createTest()方法中做这件事比较合适:
@Override
protected Object createTest() throws Exception {
Object testObject = super.createTest();
// 找出所有带有@FieldBefore注解的属性
List<Field> fields = getFieldBefores();
for (Field field : fields) {
// 必须设置为true, 否则调用后一句会抛异常
field.setAccessible(true);
field.set(testObject, field.getType().newInstance());
}
return testObject;
}
参照查找@Before 注解的方法的代码, 查找所有带@FieldBefore的方法:
public List<Field> getFieldBefores() {
List<Field> results = new ArrayList<Field>();
for (Class<?> eachClass : getSuperClasses(getTestClass().getJavaClass())) {
Field[] fields = eachClass.getDeclaredFields();
for (Field field : fields) {
Annotation annotation = field.getAnnotation(FieldBefore.class);
if (annotation != null && !isShadowed(field, results))
results.add(field);
}
}
Collections.reverse(results);
return results;
}
private List<Class<?>> getSuperClasses(Class<?> testClass) {
ArrayList<Class<?>> results = new ArrayList<Class<?>>();
Class<?> current = testClass;
while (current != null) {
results.add(current);
current = current.getSuperclass();
}
return results;
}
private boolean isShadowed(Field field, List<Field> results) {
for (Field each : results) {
if (isShadowed(field, each))
return true;
}
return false;
}
private boolean isShadowed(Field current, Field previous) {
if (!previous.getName().equals(current.getName()))
return false;
return true;
}
最后是@FieldBefore的定义:
/**
* 在每次执行方法前, 对属性执行初始化
* @author xxx
* @since 2009-2-12 下午07:31:03
*/
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD })
public @interface FieldBefore {
}
用法如下:
public class Mock {
public String str;
public Mock() {
str = "init";
}
}
public class MockBeforeTest {
@FieldBefore
private static Mock mock;
// override the super field annotation init
private static Mock mock1;
@Test
public void testModth() {
Assert.assertNull(mock1);
System.out.println(mock.str);
Assert.assertNotNull(mock);
Assert.assertEquals(mock.str, "init");
}
}