全国城市切换

关于Junit的 源码解析

作者:郑州知网 日期:2020-07-15 人气:8389



junit4 下的所有的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
 */
@Deprecated
public 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}.
 */
@Deprecated
public 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}.
 */
@Deprecated
public 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"));
		}
	}
}


你觉得这篇文章怎么样?

00

快捷导航

直销解释定义是 直销公司怎么样 做直销的优势 分销如何做小程序 企业直销软件研发 外贸分销平台 怎么做分销小程序 直销公司怎样选择 直销是现在的趋势 分销网站系统 我直销 商城如何做分销 哪个直销好 网站分销 做直销属于什么 外贸货源分销平台 哪个分销系统好 哪个分销平台 订货通分销 直销软件多少钱一个 三级分销平台 直销软件研发开发 如何选直销公司 分销项目 分销价格 三级分销的模式 在线分销 门店分销系统 怎样做分销平台 什么是互联网加直销