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