1package org.junit.rules;
2
3import org.junit.runner.Description;
4import org.junit.runners.model.Statement;
5
6/**
7 * A base class for Rules (like TemporaryFolder) that set up an external
8 * resource before a test (a file, socket, server, database connection, etc.),
9 * and guarantee to tear it down afterward:
10 *
11 * <pre>
12 * public static class UsesExternalResource {
13 *  Server myServer= new Server();
14 *
15 *  &#064;Rule
16 *  public ExternalResource resource= new ExternalResource() {
17 *      &#064;Override
18 *      protected void before() throws Throwable {
19 *          myServer.connect();
20 *         };
21 *
22 *      &#064;Override
23 *      protected void after() {
24 *          myServer.disconnect();
25 *         };
26 *     };
27 *
28 *  &#064;Test
29 *  public void testFoo() {
30 *      new Client().run(myServer);
31 *     }
32 * }
33 * </pre>
34 *
35 * @since 4.7
36 */
37public abstract class ExternalResource implements TestRule {
38    public Statement apply(Statement base, Description description) {
39        return statement(base);
40    }
41
42    private Statement statement(final Statement base) {
43        return new Statement() {
44            @Override
45            public void evaluate() throws Throwable {
46                before();
47                try {
48                    base.evaluate();
49                } finally {
50                    after();
51                }
52            }
53        };
54    }
55
56    /**
57     * Override to set up your specific external resource.
58     *
59     * @throws Throwable if setup fails (which will disable {@code after}
60     */
61    protected void before() throws Throwable {
62        // do nothing
63    }
64
65    /**
66     * Override to tear down your specific external resource.
67     */
68    protected void after() {
69        // do nothing
70    }
71}
72