`

JunitRunner定制之模仿@Before对属性进行初始化

    博客分类:
  • Test
阅读更多
在测试的过程中, 会用到一些模拟数据, 希望在每次调用测试方法之间对这些数据进行一下初始化,类似@Before注解的方法, 在调用测试方法之间被调用一次, 我希望通过注解来做这件事儿.于是有了下面的做法:
通过阅读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");
	}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics