OptionalCactusTestCase.java |
package org.mockejb; import java.lang.reflect.*; import org.apache.cactus.*; /** * Runs the test case on the server side under cactus or * standalone on the client side. Concrete test cases extend this * class. * * If "mockejb.cactus.mode" system property is set to true, the test case * behaves as the Cactus' ServletTestCase, so it runs * on the server. * If the property is false or not set, Cactus is ignored completely and the test * class runs on the client under JUnit. * Subclasses can override <code>isCactusEnabled()</code> to use a different * mechanism for turning cactus mode on and off. * * @author Alexander Ananiev */ public class OptionalCactusTestCase extends ServletTestCase { /** * Creates a new TestCase for the given test. * @param testName test name */ public OptionalCactusTestCase(String testName ) { super( testName ); } /** * Tests if the test should run in Cactus mode. Cactus * mode is turned on if the system property "mockejb.cactus.mode" is set * to "true". * Subclasses can implement different way of specifying Cactus mode. * * @return true if "mockejb.cactus" system property set to true */ protected boolean isCactusMode(){ String cactusProp = System.getProperty("mockejb.cactus.mode"); return (cactusProp!=null && cactusProp.equalsIgnoreCase("true")); } /** * Tests if the test is being executed on the app server. * @return true if the test runs on the app server */ public boolean isRunningOnServer(){ return ( this.request != null ); } /** * Overrides the standard JUnit and Cactus method. * This allows to * turn the cactus off for this test class even though it continues * to extend ServletTestCase. * The method first checks if the test runs on the client, in * which case it calls <code>runBareLocally</code>/ * If the test runs on the server, it calls "super" to * delegate running the test to ServletTestCase * * @throws Throwable in case of any problems in the test * * @see junit.framework.TestCase#runBare() */ public void runBare() throws Throwable { // if we are called on the client if ( ! isRunningOnServer() ) { runBareLocally(); } // on the server else { super.runBare(); } } /** * This method is called by <code>runBare</code> when it * determines that the test is running locally (on the client). * If the cactus is "on", this method simply calls "super". * If the cactus is "off", it runs the code copied from * JUnit, therefore disabling the override in Cactus. * * @throws Throwable in case of any problems in the test */ protected void runBareLocally() throws Throwable { if ( isCactusMode() ) { super.runBare(); } else { setUp(); try { runTestLocally(); } finally { tearDown(); } } } /** * Invokes the test method using reflection. * Standard JUnit logic is duplicated here. * Using this method instead of <code>runTest()</code> enforces * that the test always runs locally (on the client). Cactus overrides <code>runTest()</code> * to run the test remotely, so using a different name ensures that it does not run. * * @see junit.framework.TestCase#runTest() * * @exception Throwable if any exception is thrown */ protected void runTestLocally() throws Throwable { assertNotNull( getName() ); Method runMethod= null; try { // use getMethod to get all public inherited // methods. getDeclaredMethods returns all // methods of this class but excludes the // inherited ones. runMethod= getClass().getMethod( getName(), null); } catch (NoSuchMethodException e) { fail("Method \""+getName()+"\" not found"); } if (!Modifier.isPublic(runMethod.getModifiers())) { fail("Method \""+getName()+"\" should be public"); } try { runMethod.invoke(this, new Class[0]); } catch (InvocationTargetException e) { e.fillInStackTrace(); throw e.getTargetException(); } catch (IllegalAccessException e) { e.fillInStackTrace(); throw e; } } }