JUnit4-Description.java源代码 解读与分析
作用域
- children 子描述集合,套件测试时,children不为空,套件测试可以由套件测试和原子测试组合而成。
- displayName 正常情况下,displayName格式都是这样的:方法名(类名),方法
formatDisplayName
就是将其方法名,类名格式化成这种形式。 - uniqueId 唯一标识符,从两个私有构造方法可看出,不对其设置的话,默认为displayName
- annotation[] 注解
- testClass 测试类
创建
由于构造方法私有化,Description的创建只能够通过静态方法来创建。
public static Description createSuiteDescription(String name, Annotation... annotations) {
return new Description(null, name, annotations);
}
public static Description createSuiteDescription(String name, Serializable uniqueId, Annotation... annotations) {
return new Description(null, name, uniqueId, annotations);
}
public static Description createTestDescription(String className, String name, Annotation... annotations) {
return new Description(null, formatDisplayName(name, className), annotations);
}
public static Description createTestDescription(Class<?> clazz, String name, Annotation... annotations) {
return new Description(clazz, formatDisplayName(name, clazz.getName()), annotations);
}
public static Description createTestDescription(Class<?> clazz, String name) {
return new Description(clazz, formatDisplayName(name, clazz.getName()));
}
public static Description createTestDescription(String className, String name, Serializable uniqueId) {
return new Description(null, formatDisplayName(name, className), uniqueId);
}
public static Description createSuiteDescription(Class<?> testClass) {
return new Description(testClass, testClass.getName(), testClass.getAnnotations());
}
方法解读
源码中,有些方法有点不好理解,这次说明一下:
1.从当前注解数组中,获取某种类型的注解.
这个方法在JUnit中涉及到注解时,就常常出现。如作用域上的注解,方法上的注解啊,测试类上的注解啊…泛型T, 继承Annotation,即T是注解类型。Class.cast(Annotation)能够将Annotation转化为T类型
public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
for (Annotation each : fAnnotations) {
if (each.annotationType().equals(annotationType)) {
return annotationType.cast(each); //相当于(T)each
}
}
return null;
}
2.获取测试类,测试类名,方法名时,这些信息都可为空,而实际上可能不为空,创建时,没有传进这些参数;但有一个信息不为空,那就是displayName, 它的格式是 方法名(类全名)
因此,在一些信息为空时,采取正则表达式匹配的方法,从displayName获取信息。
正则表达式中, 组是用括号划分的正则表达式,([\\s\\S]*)\\((.*)\\)
中,第0组是整个表达式,第1组是[\\s\\S]*
表示方法名, 第二组是.*
,表示类全名。在下面方法中,如果匹配的话(matcher.matches()
), 那么就会根据组数group来获取对应的信息。
private static final Pattern METHOD_AND_CLASS_NAME_PATTERN = Pattern
.compile("([\\s\\S]*)\\((.*)\\)");
private String methodAndClassNamePatternGroupOrDefault(int group,
String defaultString) {
Matcher matcher = METHOD_AND_CLASS_NAME_PATTERN.matcher(toString());
return matcher.matches() ? matcher.group(group) : defaultString;
}
//获取方法名 group = 1
public String getMethodName() {
return methodAndClassNamePatternGroupOrDefault(1, null);
}
//获取类名, testClass不为空时,直接getName()获取,否则group=2
public String getClassName() {
return fTestClass != null ? fTestClass.getName() : methodAndClassNamePatternGroupOrDefault(2, toString());
}
//获取测试类时,testClass为空时,尝试根据className, 使用Class.forName()获取
public Class<?> getTestClass() {
if (fTestClass != null) {
return fTestClass;
}
String name = getClassName();