关于Junit的 源码解析
发布时间:2019-11-04

unit4 下的所有的testcase都是在Runner下执行的, 可以将Runner理解为junit运行的容器, 默认情况下junit会使用JUnit4ClassRunner作为所有testcase的执行容器。

如果要定制自己的junit, 则可以实现自己的Runner,最简单的办法就是Junit4ClassRunner继承, spring-test, unitils这些框架就是采用这样的做法。

如在spring中是SpringJUnit4ClassRunner, 在unitils中是UnitilsJUnit4TestClassRunner, 一般我们的testcase都是在通过eclipse插件来执行的, eclipse的junit插件会在执行的时候会初始化指定的Runner。初始化的过程可以在ClassRequest中找到。


package org.junit.internal.runners;import java.lang.annotation.Annotation;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Collections;import java.util.Comparator;import java.util.Iterator;import java.util.List;import org.junit.runner.Description;import org.junit.runner.Runner;import org.junit.runner.manipulation.Filter;import org.junit.runner.manipulation.Filterable;import org.junit.runner.manipulation.NoTestsRemainException;import org.junit.runner.manipulation.Sortable;import org.junit.runner.manipulation.Sorter;import org.junit.runner.notification.Failure;import org.junit.runner.notification.RunNotifier;import org.junit.runners.BlockJUnit4ClassRunner;/** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be *             removed in the next release. Please use *             {@link BlockJUnit4ClassRunner} in place of *             {@link JUnit4ClassRunner}. *  *             This may disappear as soon as 1 April 2009 */@Deprecatedpublic class JUnit4ClassRunner extends Runner implements Filterable, Sortable{    private final ListfTestMethods;    private TestClass fTestClass;	    //将要测试的TestCase实例Class对象传入    public JUnit4ClassRunner(Class klass) throws InitializationError    {        fTestClass = new TestClass(klass);        fTestMethods = getTestMethods();        //对要进行测试的方法展开验证        validate();    }        //获取@test的方法List    protected ListgetTestMethods()    {        return fTestClass.getTestMethods();    }	    //对要进行测试的方法展开验证    protected void validate() throws InitializationError    {        MethodValidator methodValidator = new MethodValidator(fTestClass);        ();        ();    }    @Override    public void run(final RunNotifier notifier)    {        new ClassRoadie(notifier, fTestClass, getDescription(), new Runnable()        {            public void run()            {                runMethods(notifier);            }        }).runProtected();    }    protected void runMethods(final RunNotifier notifier)    {        for (Method method : fTestMethods)            invokeTestMethod(method, notifier);    }    @Override    public Description getDescription()    {        Description spec = (getName(), classAnnotations());        ListtestMethods = fTestMethods;        for (Method method : testMethods)            (methodDescription(method));        return spec;    }    protected Annotation[] classAnnotations()    {        return fTestClass.getJavaClass().getAnnotations();    }    protected String getName()    {        return getTestClass().getName();    }    protected Object createTest() throws Exception    {        return getTestClass().getConstructor().newInstance();    }    protected void invokeTestMethod(Method method, RunNotifier notifier)    {        Description description = methodDescription(method);        Object test;        try        {            test = createTest();        }        catch(InvocationTargetException e)        {            testAborted(notifier, description, ());            return;        }        catch(Exception e)        {            testAborted(notifier, description, e);            return;        }        TestMethod testMethod = wrapMethod(method);        new MethodRoadie(test, testMethod, notifier, description).run();    }    private void testAborted(RunNotifier notifier, Description description, Throwable e)    {        (description);        (new Failure(description, e));        (description);    }    protected TestMethod wrapMethod(Method method)    {        return new TestMethod(method, fTestClass);    }    protected String testName(Method method)    {        return method.getName();    }    protected Description methodDescription(Method method)    {        return Description.createTestDescription(getTestClass().getJavaClass(), testName(method), testAnnotations(method));    }    protected Annotation[] testAnnotations(Method method)    {        return method.getAnnotations();    }    public void filter(Filter filter) throws NoTestsRemainException    {        for (Iteratoriter = (); ();)        {            Method method = ();            if (!(methodDescription(method)))                ();        }        if (())            throw new NoTestsRemainException();    }    public void sort(final Sorter sorter)    {        (fTestMethods, new Comparator()        {            public int compare(Method o1, Method o2)            {                return sorter.compare(methodDescription(o1), methodDescription(o2));            }        });    }    protected TestClass getTestClass()    {        return fTestClass;    }}

不同于上一节提到的类

package org.junit.internal.runners;import java.lang.annotation.Annotation;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Collections;import java.util.List;import org.junit.AfterClass;import org.junit.Before;import org.junit.BeforeClass;import org.junit.Test;import org.junit.runners.BlockJUnit4ClassRunner;/** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be *             removed in the next release. Please use *             {@link BlockJUnit4ClassRunner} in place of *             {@link JUnit4ClassRunner}. */@Deprecatedpublic class TestClass{    private final Class fClass;    public TestClass(Class klass)    {        fClass = klass;    }    public ListgetTestMethods()    {        return getAnnotatedMethods();    }    ListgetBefores()    {        return getAnnotatedMethods();    }    ListgetAfters()    {        return getAnnotatedMethods();    }    public ListgetAnnotatedMethods(Class annotationClass)    {        Listresults = new ArrayList();        for (Class eachClass : getSuperClasses(fClass))        {            Method[] methods = ();            for (Method eachMethod : methods)            {                Annotation annotation = (annotationClass);                if (annotation != null && !isShadowed(eachMethod, results))                    (eachMethod);            }        }        if (runsTopToBottom(annotationClass))            (results);        return results;    }    private boolean runsTopToBottom(Class annotation)    {        return () || ();    }    private boolean isShadowed(Method method, Listresults)    {        for (Method each : results)        {            if (isShadowed(method, each))                return true;        }        return false;    }    private boolean isShadowed(Method current, Method previous)    {        if (!().equals(()))            return false;        if (().length != ().length)            return false;        for (int i = 0; i < ().length; i++)        {            if (!()[i].equals(()[i]))                return false;        }        return true;    }    private List<Class> getSuperClasses(Class testClass)    {        ArrayList<Class> results = new ArrayList<Class>();        Class current = testClass;        while (current != null)        {            (current);            current = ();        }        return results;    }    public Constructor getConstructor() throws SecurityException, NoSuchMethodException    {        return fClass.getConstructor();    }    public Class getJavaClass()    {        return fClass;    }    public String getName()    {        return fClass.getName();    }}

用于在 类当中进行方法验证

package org.junit.internal.runners;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.ArrayList;import java.util.List;import org.junit.After;import org.junit.AfterClass;import org.junit.Before;import org.junit.BeforeClass;import org.junit.Test;import org.junit.runners.BlockJUnit4ClassRunner;/** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be *             removed in the next release. Please use *             {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}. */@Deprecatedpublic class MethodValidator {	private final ListfErrors= new ArrayList();	private TestClass fTestClass;    	//类中	//validate()方法中调用该构造函数-----第一步	public MethodValidator(TestClass testClass) {		fTestClass = testClass;	}	public void validateInstanceMethods() {		validateTestMethods(After.class, false);		validateTestMethods(, false);		validateTestMethods(, false);				Listmethods= ();		if (() == 0)			(new Exception("No runnable methods"));	}	public void validateStaticMethods() {		validateTestMethods(, true);		validateTestMethods(, true);	}		//Junit4ClassRunner类中调用第二步	public ListvalidateMethodsForDefaultRunner() {		//校验无参构造方法		validateNoArgConstructor();		//校验注解方法		validateStaticMethods();		validateInstanceMethods();		return fErrors;	}		//Junit4ClassRunner类中第三步	public void assertValid() throws InitializationError {		if (!())			throw new InitializationError(fErrors);	}	public void validateNoArgConstructor() {		try {			();		} catch (Exception e) {			(new Exception("Test class should have public zero-argument constructor", e));		}	}	    //校验要测试的方法 是否静态方法、是否public方法、是否返回值void、是否无参数	//@param annotation 要测试的annotation类  	//@param isStatic 是否要求静态方法	private void validateTestMethods(Class annotation,boolean isStatic) {		Listmethods= (annotation);				for (Method each : methods) {			if ((()) != isStatic) {				String state= isStatic ? "should" : "should not";				(new Exception("Method " + () + "() "						+ state + " be static"));			}			if (!(().getModifiers()))				(new Exception("Class " + ().getName()						+ " should be public"));			if (!(()))				(new Exception("Method " + ()						+ " should be public"));			if (() != )				(new Exception("Method " + ()						+ " should be void"));			if (().length != 0)				(new Exception("Method " + ()						+ " should have no parameters"));		}	}}



泰州润扬网络策划服务有限公司专注泰州网络公司,泰州网站建设,

从域名选择-工信部备案-首页风格确认-内页栏目设置-内页框架设计-后台搭建管理-新闻定期发布-定期优化设置-效果统计-月度反馈。

泰州网站建设,泰州网络推广,交给我们:放心、省心。

我们不做第一,只做唯一,以真诚服务、实在做事的态度为您做好交给我们的每一项工作。

泰州网络公司、泰州网站建设、泰州网络策划、泰州APP开发、泰州网络推广、泰州微信营销、泰州百度信息流推广,泰州软件开发泰州百度爱采购

本文由:润扬网络策划编辑部小编 整理发布、翻版必究 ,如涉及各项侵权请及时与我们联系修改:13961039617    合作热线:19825583557  我们期待与您合作