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