• JUnit4.12 源码分析之Statement


    1. Statement

    • 抽象类Statement作为命令模式的Command,只有一个方法
    • 各种Runner作为命令模式中的Invoker,将发出各种Statement,来表示它们运行JUnit测试的整个过程;
    • org.junit.internal.runners.statement包中定义了Statement的子类(具体命令),来处理针对方法
      的标注,如@Test,@Before,@After,@BeforeClass,@AfterClass;
    // org.junit.runners.model.Statement
    public abstract class Statement{
    
        public abstract void evalute() throws Throwable;
    
    }
    
    // BlockJUnit4ClassRunner 中的符合命令,来处理 @Test, @Before, @After...
    // org.junit.runners.BlockJUnit4ClassRunner
    
    public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethoc>{
        ...(略)
    
        protected Statement methodBlock(FrameworkMethod method){
            Object test;
            try{
                test = new ReflectiveCallable(){
                    @Override
                    protected Object runReflectiveCall() throws Throwable{
                        return createTest();
                    }
                }.run();
            }catch(Throwable e){
                return new Fail(e);
            }
    
            // 各种Statement
            Statement statement = methodInvoker(method, test);
            statement = possiblyExpectingExceptions(method, test, statement);
            statement = withPotentialTimeout(method, test, statement);
            statement = withBefores(method, test, statement);
            statement = withAfters(method, test, statement);
            statement = withRules(method, test, statement);
            return statement;
        }
    
        // 根据反射,执行无参构造函数
        protected Object createTest() throws Exception{
            return getTestClass().getOnlyConstructor().newInstance();
        }
    
        // Statement builders
        protected Statement methodInvoker(FrameworkMethod method, Object test){
            return new InvokeMethod(method, test);
        }
    }
    

    2.Statement 的实现类

    • org.junit.internal.runners.statements包下
      • ExpectException
      • Fail
      • FailOnTimeOut
      • InvokeMethod
      • RunAfters
      • RunBefores
    // @Test(expected=IndexOutOfBoundsException.class)
    
    // 源码 org.junit.internal.runners.statements.ExpectException
    public class ExpectException extends Statement{
        private final Statement next;
        private final Class<? extends Throwable> expected;
    
        public ExpectException(Statement next, Class<? extends Throwable> expected){
            this.next = next;
            this.expected = expected;
        }
    
        @Override
        public void evalute() throws Exception{
            boolean complete = false;
            try{
                next.evalute();
                complete = true;
            }catch(AssumptionViolatedException e){
                throw e;
            }catch(Throwable e){
                if(!expected.isAssignableFrom(e.getClass())){
                    String message = "Unexpected exception, expected<"
                            + expected.getName() + "> but was<"
                            + e.getClass().getName() + ">";
                    throw new Exception(messge, e);
                }
            }
            if(complete){
                throw new AssertionError("Expected exception: "
                        + expected.getName());
            }
        }
    }
    

    参考资料:

  • 相关阅读:
    pip错误:'utf-8' codec can't decode byte解决方法
    windows中python2与python3共存
    Alpha 冲刺 (3/10)
    Alpha 冲刺 (2/10)
    Alpha 冲刺 (1/10)
    项目需求分析报告答辩总结
    项目选题报告答辩总结
    项目UML设计(团队)
    # 第七次作业--项目需求分析(团队)
    结对项目--第二次作业
  • 原文地址:https://www.cnblogs.com/linkworld/p/9061967.html
Copyright © 2020-2023  润新知