1. Statement
- 抽象类Statement作为命令模式的Command,只有一个方法
- 各种
Runner
作为命令模式中的Invoker
,将发出各种Statement,来表示它们运行JUnit测试的整个过程; org.junit.internal.runners.statement
包中定义了Statement的子类(具体命令),来处理针对方法 的标注,如@Test
,@Before
,@After
,@BeforeClass
,@AfterClass
;
// org.junit.runners.model.Statementpublic abstract class Statement{ public abstract void evalute() throws Throwable;}// BlockJUnit4ClassRunner 中的符合命令,来处理 @Test, @Before, @After...// org.junit.runners.BlockJUnit4ClassRunnerpublic class BlockJUnit4ClassRunner extends ParentRunner{ ...(略) 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.ExpectExceptionpublic class ExpectException extends Statement{ private final Statement next; private final Class expected; public ExpectException(Statement next, Class 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()); } }}
参考资料: