Home | History | Annotate | Download | only in framework
      1 package junit.framework;
      2 
      3 import java.lang.reflect.InvocationTargetException;
      4 import java.lang.reflect.Method;
      5 import java.lang.reflect.Modifier;
      6 
      7 /**
      8  * A test case defines the fixture to run multiple tests. To define a test case<br/>
      9  * <ol>
     10  *   <li>implement a subclass of <code>TestCase</code></li>
     11  *   <li>define instance variables that store the state of the fixture</li>
     12  *   <li>initialize the fixture state by overriding {@link #setUp()}</li>
     13  *   <li>clean-up after a test by overriding {@link #tearDown()}.</li>
     14  * </ol>
     15  * Each test runs in its own fixture so there
     16  * can be no side effects among test runs.
     17  * Here is an example:
     18  * <pre>
     19  * public class MathTest extends TestCase {
     20  *    protected double fValue1;
     21  *    protected double fValue2;
     22  *
     23  *    protected void setUp() {
     24  *       fValue1= 2.0;
     25  *       fValue2= 3.0;
     26  *    }
     27  * }
     28  * </pre>
     29  *
     30  * For each test implement a method which interacts
     31  * with the fixture. Verify the expected results with assertions specified
     32  * by calling {@link junit.framework.Assert#assertTrue(String, boolean)} with a boolean.
     33  * <pre>
     34  *    public void testAdd() {
     35  *       double result= fValue1 + fValue2;
     36  *       assertTrue(result == 5.0);
     37  *    }
     38  * </pre>
     39  *
     40  * Once the methods are defined you can run them. The framework supports
     41  * both a static type safe and more dynamic way to run a test.
     42  * In the static way you override the runTest method and define the method to
     43  * be invoked. A convenient way to do so is with an anonymous inner class.
     44  * <pre>
     45  * TestCase test= new MathTest("add") {
     46  *    public void runTest() {
     47  *       testAdd();
     48  *    }
     49  * };
     50  * test.run();
     51  * </pre>
     52  *
     53  * The dynamic way uses reflection to implement {@link #runTest()}. It dynamically finds
     54  * and invokes a method.
     55  * In this case the name of the test case has to correspond to the test method
     56  * to be run.
     57  * <pre>
     58  * TestCase test= new MathTest("testAdd");
     59  * test.run();
     60  * </pre>
     61  *
     62  * The tests to be run can be collected into a TestSuite. JUnit provides
     63  * different <i>test runners</i> which can run a test suite and collect the results.
     64  * A test runner either expects a static method <code>suite</code> as the entry
     65  * point to get a test to run or it will extract the suite automatically.
     66  * <pre>
     67  * public static Test suite() {
     68  *    suite.addTest(new MathTest("testAdd"));
     69  *    suite.addTest(new MathTest("testDivideByZero"));
     70  *    return suite;
     71  * }
     72  * </pre>
     73  * @see TestResult
     74  * @see TestSuite
     75  */
     76 public abstract class TestCase extends Assert implements Test {
     77 	/**
     78 	 * the name of the test case
     79 	 */
     80 	private String fName;
     81 
     82 	/**
     83 	 * No-arg constructor to enable serialization. This method
     84 	 * is not intended to be used by mere mortals without calling setName().
     85 	 */
     86 	public TestCase() {
     87 		fName= null;
     88 	}
     89 	/**
     90 	 * Constructs a test case with the given name.
     91 	 */
     92 	public TestCase(String name) {
     93 		fName= name;
     94 	}
     95 	/**
     96 	 * Counts the number of test cases executed by run(TestResult result).
     97 	 */
     98 	public int countTestCases() {
     99 		return 1;
    100 	}
    101 	/**
    102 	 * Creates a default TestResult object
    103 	 *
    104 	 * @see TestResult
    105 	 */
    106 	protected TestResult createResult() {
    107 	    return new TestResult();
    108 	}
    109 	/**
    110 	 * A convenience method to run this test, collecting the results with a
    111 	 * default TestResult object.
    112 	 *
    113 	 * @see TestResult
    114 	 */
    115 	public TestResult run() {
    116 		TestResult result= createResult();
    117 		run(result);
    118 		return result;
    119 	}
    120 	/**
    121 	 * Runs the test case and collects the results in TestResult.
    122 	 */
    123 	public void run(TestResult result) {
    124 		result.run(this);
    125 	}
    126 	/**
    127 	 * Runs the bare test sequence.
    128 	 * @throws Throwable if any exception is thrown
    129 	 */
    130 	public void runBare() throws Throwable {
    131 		Throwable exception= null;
    132 		setUp();
    133 		try {
    134 			runTest();
    135 		} catch (Throwable running) {
    136 			exception= running;
    137 		}
    138 		finally {
    139 			try {
    140 				tearDown();
    141 			} catch (Throwable tearingDown) {
    142 				if (exception == null) exception= tearingDown;
    143 			}
    144 		}
    145 		if (exception != null) throw exception;
    146 	}
    147 	/**
    148 	 * Override to run the test and assert its state.
    149 	 * @throws Throwable if any exception is thrown
    150 	 */
    151 	protected void runTest() throws Throwable {
    152 		assertNotNull("TestCase.fName cannot be null", fName); // Some VMs crash when calling getMethod(null,null);
    153 		Method runMethod= null;
    154 		try {
    155 			// use getMethod to get all public inherited
    156 			// methods. getDeclaredMethods returns all
    157 			// methods of this class but excludes the
    158 			// inherited ones.
    159 			runMethod= getClass().getMethod(fName, (Class[])null);
    160 		} catch (NoSuchMethodException e) {
    161 			fail("Method \""+fName+"\" not found");
    162 		}
    163 		if (!Modifier.isPublic(runMethod.getModifiers())) {
    164 			fail("Method \""+fName+"\" should be public");
    165 		}
    166 
    167 		try {
    168 			runMethod.invoke(this);
    169 		}
    170 		catch (InvocationTargetException e) {
    171 			e.fillInStackTrace();
    172 			throw e.getTargetException();
    173 		}
    174 		catch (IllegalAccessException e) {
    175 			e.fillInStackTrace();
    176 			throw e;
    177 		}
    178 	}
    179 	/**
    180 	 * Sets up the fixture, for example, open a network connection.
    181 	 * This method is called before a test is executed.
    182 	 */
    183 	protected void setUp() throws Exception {
    184 	}
    185 	/**
    186 	 * Tears down the fixture, for example, close a network connection.
    187 	 * This method is called after a test is executed.
    188 	 */
    189 	protected void tearDown() throws Exception {
    190 	}
    191 	/**
    192 	 * Returns a string representation of the test case
    193 	 */
    194 	@Override
    195 	public String toString() {
    196 	    return getName() + "(" + getClass().getName() + ")";
    197 	}
    198 	/**
    199 	 * Gets the name of a TestCase
    200 	 * @return the name of the TestCase
    201 	 */
    202 	public String getName() {
    203 		return fName;
    204 	}
    205 	/**
    206 	 * Sets the name of a TestCase
    207 	 * @param name the name to set
    208 	 */
    209 	public void setName(String name) {
    210 		fName= name;
    211 	}
    212 }
    213