JUnit4.8.2 source code analysis-5.1 Statement compound command

Source: Internet
Author: User

JUnit4.8.2 source code analysis-5.1 Statement compound command

Abstract class StatementCommand in Command mode, There is only one public synchronized actvoidEvaluate() Throws Throwable;

As the Runner of Invoker in command mode, various Statement will be issued and they represent the entire process of running the JUnit test group. For method annotation such as @ Test, @ Before, @ After, @ BeforeClass, @ AfterClass, and various Test scenarios, JUnit is in org. junit.Internal. runners. statements packageDefines the sub-class of Statement-specific commands.

To Test a method, you must determine the ExpectException and FailOnTimeout of @ Test, process RunBefores and RunAfters, and handle Rule ...... This requires a larger Statement --Compound command.

ParentRunner And BlockJUnit4ClassRunner have long code to do this. Yqj2065 is a little strange: According to the Erich Gamma style, every type is too short. Why not extract the composite command?

Taking BlockJUnit4ClassRunner as an example, design a MethodBlock, regardless of. junit. the runners package is still used as a tool in org. junit. internal. runners. the statements package is compatible with other sub-classes of Statement (specific commands. Put the relevant code in MethodBlock, Which is easy and clear. The following approximate180 lines of codeIt's easy to extract from BlockJUnit4ClassRunner.

In the following code, the parameters of the auxiliary methods can be omitted.

Package org. junit. runners; import java. util. list; import org. junit. after; import org. junit. before; import org. junit. ignore; import org. junit. rule; import org. junit. test; import org. junit. test. none; import org. junit. runners. model. statement; import org. junit. runners. model. testClass; import org. junit. runners. model. frameworkField; import org. junit. runners. model. frameworkMethod; import org. junit. internal. runners. statements. expectException; import org. junit. internal. runners. statements. fail; import org. junit. internal. runners. statements. failOnTimeout; import org. junit. internal. runners. statements. invokeMethod; import org. junit. internal. runners. statements. runAfters; import org. junit. internal. runners. statements. runBefores; import org. junit. rules. methodRule;/*** Returns a Statement that, when executed, either returns normally if * {@ code method} passes, or throws an exception if {@ code method} fails. ** Here is an outline of the default implementation :**
 
 
    *
  • Invoke {@ code method} on the result of {@ code createTest ()}, and * throw any exceptions thrown by either operation .*
  • HOWEVER, if {@ code method}'s {@ code @ Test} annotation has the {@ code * expecting} attribute, return normally only if the previous step threw an * exception of the correct type, and throw an exception otherwise. *
  • HOWEVER, if {@ code method}'s {@ code @ Test} annotation has the {@ code * timeout} attribute, throw an exception if the previous step takes more * than the specified number of milliseconds. *
  • ALWAYS allow {@ code @ Rule} fields to modify the execution of the * above steps. A {@ code Rule} may prevent all execution of the above steps, * or add additional behavior before and after, or modify thrown exceptions. * For more information, see {@ link MethodRule }*
  • ALWAYS run all non-overridden {@ code @ Before} methods on this class * and superclasses before any of the previous steps; if any throws an * Exception, stop execution and pass the exception on. *
  • ALWAYS run all non-overridden {@ code @ After} methods on this class * and superclasses after any of the previous steps; all After methods are * always executed: exceptions thrown by previous steps are combined, if * necessary, with exceptions from After methods into a * {@ link MultipleFailureException }. *
** This can be overridden in subclasses, either by overriding this method, * or the implementations creating each sub-statement. */public class MethodBlock extends Statement {private Statement statement; private final FrameworkMethod method; private final Object test; public MethodBlock (FrameworkMethod, Object target) {this. method = method; test = target;} private void decorator () {statemen T = 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 );} /** BlockJUnit4ClassRunner * Except makeNotifier * // Statement builders // *** Returns a {@ link Statement} that invokes {@ code method} on {@ code test} */protected Statement methodInvoker (FrameworkMethod method, Object test) {return new InvokeMethod (method, test );} /*** Returns a {@ link Statement}: if {@ code method}'s {@ code @ Test} annotation * has the {@ code expecting} attribute, return normally only if {@ code next} * throws an exception of the correct type, and throw an exception * oth Erwise. ** @ deprecated Will be private soon: use Rules instead */@ Deprecated protected Statement possiblyExpectingExceptions (FrameworkMethod method, Object test, Statement next) {Test annotation = method. getAnnotation (Test. class); return expectsException (annotation )? New ExpectException (next, getExpectedException (annotation): next;}/*** Returns a {@ link Statement }: if {@ code method}'s {@ code @ Test} annotation * has the {@ code timeout} attribute, throw an exception if {@ code next} * takes more than the specified number of milliseconds. ** @ deprecated Will be private soon: use Rules instead */@ Deprecated protected Statement withPotentialTimeout (FrameworkM Ethod method, Object test, Statement next) {long timeout = getTimeout (method. getAnnotation (Test. class); return timeout> 0? New FailOnTimeout (next, timeout): next;}/*** Returns a {@ link Statement }: run all non-overridden {@ code @ Before} * methods on this class and superclasses before running {@ code next}; if * any throws an Exception, stop execution and pass the exception on. ** @ deprecated Will be private soon: use Rules instead */@ Deprecated protected Statement witequalfores (FrameworkMethod method, Object target, Statement statement) {List <frameworkMethod> befores = getTestClass (). getAnnotatedMethods (Before. class); return befores. isEmpty ()? Statement: new RunBefores (statement, befores, target);}/*** Returns a {@ link Statement }: run all non-overridden {@ code @ After} * methods on this class and superclasses before running {@ code next}; all * After methods are always executed: exceptions thrown by previous steps * are combined, if necessary, with exceptions from After methods into a * {@ link MultipleFailureException }. ** @ deprecate D Will be private soon: use Rules instead */@ Deprecated protected Statement withAfters (FrameworkMethod method, Object target, Statement statement) {List <frameworkMethod> afters = getTestClass (). getAnnotatedMethods (After. class); return afters. isEmpty ()? Statement: new RunAfters (statement, afters, target);} private Statement withRules (FrameworkMethod method, Object target, Statement statement) {Statement result = statement; for (MethodRule each: getTestClass (). getAnnotatedFieldValues (target, Rule. class, MethodRule. class) result = each. apply (result, method, target); return result;} private Class GetExpectedException (Test annotation) {if (annotation = null | annotation. expected () = None. class) return null; else return annotation. expected ();} private boolean expectsException (Test annotation) {return getExpectedException (annotation )! = Null;} private long getTimeout (Test annotation) {if (annotation = null) return 0; return annotation. timeout ();} public final TestClass getTestClass () {// ParentRunner . Validate ()? Return new TestClass (test. getClass () ;}@ Override public void evaluate () throws Throwable {this. decorator (); statement. evaluate ();}}
In BlockJUnit4ClassRunner, you only need to set methodBlock (method). evaluate ();

Change to new MethodBlock (method, test). evaluate ();




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.