Package ch.inftec.ju.testing.db

Source Code of ch.inftec.ju.testing.db.AbstractDbTest

package ch.inftec.ju.testing.db;

import java.lang.reflect.Method;

import javax.persistence.EntityManager;

import org.junit.After;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.inftec.ju.db.EmfWork;
import ch.inftec.ju.db.JuEmUtil;
import ch.inftec.ju.db.JuEmfUtil;
import ch.inftec.ju.util.TestUtils;

/**
* Base class for DB tests.
* <p>
* Provides a machanism to evaluate the test DB at runtime, thus enabling DB tests
* targeting various DB implementations.
* @author Martin
*
*/
public class AbstractDbTest {
  protected final Logger logger = LoggerFactory.getLogger(this.getClass());
 
  protected EntityManager em;
  protected JuEmUtil emUtil;
 
  private JuEmfUtil emfUtil;
  private EmfWork emfWork;
 
  /**
   * Rule to initialize DB fields. We need to use a rule so we can evaluate the method
   * annotation.
   */
  @Rule
  public DbInitializerRule dbInitializer = new DbInitializerRule(this);
 
  @After
  public void cleanupDb() {
    if (this.emfWork != null) {
      this.emfWork.close();
      this.emfWork = null;
      this.em = null;
    }
  }

  /**
   * Sets the transaction to rollback.
   */
  protected final void setRollbackOnly() {
    this.emfWork.setRollbackOnly();
  }
 
  /**
   * Starts a new EmfWork. The caller is responsible to close the work.
   * @return EmfWork with a new transaction
   */
  protected final EmfWork startNewWork() {
    return this.emfUtil.startWork();
  }
 
  /**
   * This method can be overridden by extending classes to run DB initialization scripts before the test is
   * actually run.
   * <p>
   * The method is self-responsible to release any resources aquired from the provided JuEmtUtil instance.
   * <p>
   * The default implementation is empty.
   * @param emfUtil JuEmfUtil instance that can be used to access the DB
   */
  protected void runDbInitializationScripts(JuEmfUtil emfUtil) {
  }
 
  private static class DbInitializerRule implements TestRule {
    private final AbstractDbTest dbTest;
   
    DbInitializerRule(AbstractDbTest dbTest) {
      this.dbTest = dbTest;
    }
   
    @Override
    public Statement apply(final Statement base, final Description description) {
      final Method method = TestUtils.getTestMethod(description);
     
      // Evaluate Persistence Unit name
      String persistenceUnit = "ju-pu-test";
      String profile = null;
     
      // Check if the persistenceUnit is overwritten by an annotation (method overrules
      // class annotation)
      JuDbTest juDbTest = method.getAnnotation(JuDbTest.class);
      if (juDbTest == null) {
        juDbTest = this.dbTest.getClass().getAnnotation(JuDbTest.class);
      }
      if (juDbTest != null) {
        persistenceUnit = juDbTest.persistenceUnit();
        profile = juDbTest.profile();
      }
     
      this.dbTest.emfUtil = new EmfUtilProvider().createEmfUtil(persistenceUnit, profile);
     
      return new Statement() {
        @Override
        public void evaluate() throws Throwable {
          // Run dbInitializationScripts
          dbTest.runDbInitializationScripts(dbTest.emfUtil);
         
          DbTestAnnotationHandler annotationHandler = new DbTestAnnotationHandler(method, description);
         
          // Run preAnnotations in own transaction
          try (EmfWork ew = dbTest.emfUtil.startWork()) {
            annotationHandler.executePreTestAnnotations(ew.getEmUtil());
          }
         
          // Initialize protected fields of test class
          dbTest.emfWork = dbTest.emfUtil.startWork();
          dbTest.em = dbTest.emfWork.getEm();
          dbTest.emUtil = new JuEmUtil(dbTest.em);
         
          // Run test method
          base.evaluate();
         
          // Run post server code in own transaction
          try (EmfWork ew = dbTest.emfUtil.startWork()) {
            annotationHandler.executePostServerCode(ew.getEmUtil());
          }
         
          // Run postAnnotations in own transaction
          try (EmfWork ew = dbTest.emfUtil.startWork()) {
            annotationHandler.executePostTestAnnotations(ew.getEmUtil());
          }
        }
      };     
    }
  }
}
TOP

Related Classes of ch.inftec.ju.testing.db.AbstractDbTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.