| 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;
}
}
}