How to combine @Rule and @ClassRule in JUnit 4.12

According to the release notes for 4.12 , you can annotate static members of a test class using both @Rule and @ClassRule:

a static member annotated with both @Rule and @ClassRule is now considered valid. This means that to perform actions both before and after the class, one rule can be used (for example, setting / disabling an external resource) and between tests (for example, reset an external resource),

I want to use this function to initialize a resource at the beginning of all tests in a file, perform some cleanup on the resource between each test and get rid of it after all tests are completed. This resource is currently represented by a class that extends ExternalResource .

In my methods beforeand afterhow can I distinguish between “before / after all tests” and “before / after each test”? Do I need to use another / user implementation for this TestRule?

+4
source share
4 answers

TestRule#apply isTest isSuite Description, , Statement TestRule.

, , , before, after, verify, beforeClass, afterClass, verifyClass:

public interface CombinedRule extends TestRule {
    default Statement apply(Statement base, Description description) {
        if (description.isTest()) {
            return new Statement() {
                public void evaluate() throws Throwable {
                    before();
                    try {
                        base.evaluate();
                        verify();
                    } finally {
                        after();
                    }
                }
            };
        }
        if (description.isSuite()) {
            return new Statement() {
                public void evaluate() throws Throwable {
                    beforeClass();
                    try {
                        base.evaluate();
                        verifyClass();
                    } finally {
                        afterClass();
                    }
                }
            };
        }
        return base;
    }

    default void before() throws Exception {
        //let the implementer decide whether this method is useful to implement
    }

    default void after() {
        //let the implementer decide whether this method is useful to implement
    }

    /**
     * Only runs for Tests that pass
     */
    default void verify() {
        //let the implementer decide whether this method is useful to implement
    }

    default void beforeClass() throws Exception {
        before();
    }

    default void afterClass() {
        after();
    }

    /**
     * Only runs for Suites that pass
     */
    default void verifyClass() {
        verify();
    }
}
+1

, @Before @After, , , @BeforeClass @AfterClass, / .

@Rule , / @ClassRule / .

ExternalResource @Rule @ClassRule, . , . , .

0

@BeforeClass @Before @AfterClass @After. pull request.

0

, TestRule, MethodRule:

public SharableExternalResource implements TestRule, MethodRule {

  public final Statement apply(
      final Statement base, Description description) {
    return
        new Statement() {
          @Override
          public void evaluate() throws Throwable {
            beforeClass();

            List<Throwable> errors = new ArrayList<Throwable>();
            try {
                base.evaluate();
            } catch (Throwable t) {
                errors.add(t);
            } finally {
                try {
                    afterClass();
                } catch (Throwable t) {
                    errors.add(t);
                }
            }
            MultipleFailureException.assertEmpty(errors);
          }
        };
  }

  public final Statement apply(
      Statement base, FrameworkMethod method, Object target) {
    return
        new Statement() {
          @Override
          public void evaluate() throws Throwable {
            before();

            List<Throwable> errors = new ArrayList<Throwable>();
            try {
                base.evaluate();
            } catch (Throwable t) {
                errors.add(t);
            } finally {
                try {
                    after();
                } catch (Throwable t) {
                    errors.add(t);
                }
            }
            MultipleFailureException.assertEmpty(errors);
          }
        };
  }

  public void beforeClass() throws Exception {
    // do nothing
  }

  protected void before() throws Exception {
    // do nothing
  }

  protected void after() throws Exception {
    // do nothing
  }

  public void afterClass() throws Exception {
    // do nothing
  }
}
0

Source: https://habr.com/ru/post/1605822/


All Articles