001package org.junit.rules;
002
003import org.junit.runner.Description;
004import org.junit.runners.model.Statement;
005
006/**
007 * A base class for Rules (like TemporaryFolder) that set up an external
008 * resource before a test (a file, socket, server, database connection, etc.),
009 * and guarantee to tear it down afterward:
010 *
011 * <pre>
012 * public static class UsesExternalResource {
013 *  Server myServer= new Server();
014 *
015 *  &#064;Rule
016 *  public ExternalResource resource= new ExternalResource() {
017 *      &#064;Override
018 *      protected void before() throws Throwable {
019 *          myServer.connect();
020 *         };
021 *
022 *      &#064;Override
023 *      protected void after() {
024 *          myServer.disconnect();
025 *         };
026 *     };
027 *
028 *  &#064;Test
029 *  public void testFoo() {
030 *      new Client().run(myServer);
031 *     }
032 * }
033 * </pre>
034 *
035 * @since 4.7
036 */
037public abstract class ExternalResource implements TestRule {
038    public Statement apply(Statement base, Description description) {
039        return statement(base);
040    }
041
042    private Statement statement(final Statement base) {
043        return new Statement() {
044            @Override
045            public void evaluate() throws Throwable {
046                before();
047                try {
048                    base.evaluate();
049                } finally {
050                    after();
051                }
052            }
053        };
054    }
055
056    /**
057     * Override to set up your specific external resource.
058     *
059     * @throws if setup fails (which will disable {@code after}
060     */
061    protected void before() throws Throwable {
062        // do nothing
063    }
064
065    /**
066     * Override to tear down your specific external resource.
067     */
068    protected void after() {
069        // do nothing
070    }
071}