/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.test; import junit.extensions.TestSetup; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Abstract class for tests that do need to run a one time setup/teardown phase.<p> * Candidate tests are the ones that setup an expensive test fixture that happens * to be reusable in subsequent tests (that is, its state is not modified running * the tests). * <p>Such tests can extend this class, implement the expensive setup/teardown * phases in {@link #oneTimeSetUp()} and {@link #oneTimeTearDown()}, and eventual * per method setup/teardown in {@link #setUpInternal()} and {@link #tearDownInternal()}. * <p> * In order to activate the one time setup the generic MyOneTimeSetupTest class will * also have to add the following static method: * <pre> * public static Test suite() { * return new OneTimeTestSetup(new MyOneTimeSetupTest()); * } * </pre> * @author Andrea Aime - TOPP * @author Gabriel Roldan - TOPP */ public abstract class OneTimeSetupTest extends TestCase { private static boolean oneTimeSetupDone; private static boolean forceOneTimeTearDown; private boolean inSetup; private boolean inTearDown; /** * Test suite wrapper * @author Andrea Aime - TOPP * @author Gabriel Roldan - TOPP */ protected static class OneTimeTestSetup extends TestSetup { private OneTimeSetupTest test; public OneTimeTestSetup(OneTimeSetupTest test) { super(new TestSuite(test.getClass())); this.test = test; } @Override protected void setUp() throws Exception { super.setUp(); oneTimeSetupDone = true; forceOneTimeTearDown = false; test.oneTimeSetUp(); } @Override protected void tearDown() throws Exception { super.tearDown(); oneTimeSetupDone = false; forceOneTimeTearDown = false; test.oneTimeTearDown(); } } /** * This provides the one time setup for the expensive fixture. The fields making up the * fixture will have to be static ones, to avoid loosing their values as JUnit goes * through the test methods (for each one a new instance of the class will be created) */ protected abstract void oneTimeSetUp() throws Exception; /** * This provides the one time teardown for the expensive fixture. */ protected abstract void oneTimeTearDown() throws Exception; /** * Provides the proper behavior so that the one time setup is run once matter how the * test is started. If you need to implement a per test method setup, override {@link #setUpInternal()} */ @Override protected final void setUp() throws Exception { if(inSetup) throw new RuntimeException("setUpInternal seems to call back to super.setUp(). " + "It should call super.setUpInternal instead"); try { inSetup = true; if(!oneTimeSetupDone) { oneTimeSetUp(); oneTimeSetupDone = true; forceOneTimeTearDown = true; } setUpInternal(); } finally { inSetup = false; } } /** * Provides the proper behavior so that the one time tear down is once no matter how the * test is started. If you need to implement a per test method setup, overide {@link #tearDownInternal()} */ @Override protected final void tearDown() throws Exception { if(inTearDown) throw new RuntimeException("tearDownInternal seems to call back to super.tearDown(). " + "It should call super.tearDownInternal instead"); try { inTearDown = true; tearDownInternal(); if(forceOneTimeTearDown) { oneTimeSetupDone = false; forceOneTimeTearDown = false; oneTimeTearDown(); } } finally { inTearDown = false; } } /** * Per method setup (fixture can be stored in non static fields) */ protected void setUpInternal() throws Exception { } /** * Per method tear down */ protected void tearDownInternal() throws Exception { } }