001 /* 002 * The MIT License 003 * 004 * Copyright (c) 2012, Ninja Squad 005 * 006 * Permission is hereby granted, free of charge, to any person obtaining a copy 007 * of this software and associated documentation files (the "Software"), to deal 008 * in the Software without restriction, including without limitation the rights 009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010 * copies of the Software, and to permit persons to whom the Software is 011 * furnished to do so, subject to the following conditions: 012 * 013 * The above copyright notice and this permission notice shall be included in 014 * all copies or substantial portions of the Software. 015 * 016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 022 * THE SOFTWARE. 023 */ 024 025 package com.ninja_squad.dbsetup; 026 027 import javax.annotation.Nonnull; 028 029 030 /** 031 * <p> 032 * This class allows speeding up test execution, by avoiding re-executing the same sequence of database operations 033 * before each test method even if each of these test methods leaves the database as it is (and only performs read-only 034 * operations, which is the most frequent case). 035 * </p> 036 * <p>Example usage:</p> 037 * <pre> 038 * // the tracker is static because JUnit uses a separate Test instance for every test method. 039 * private static DbSetupTracker dbSetupTracker = new DbSetupTracker(); 040 * 041 * @Before 042 * public void setUp() throws Exception { 043 * Operation operation = 044 * Operations.sequenceOf( 045 * CommonOperations.DELETE_ALL, 046 * CommonOperations.INSERT_REFERENCE_DATA, 047 * Operations.insertInto("CLIENT") 048 * .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "COUNTRY_ID") 049 * .values(1L, "John", "Doe", "1975-07-19", 1L) 050 * .values(2L, "Jack", "Smith", "1969-08-22", 2L) 051 * .build()); 052 * DbSetup dbSetup = new DbSetup(new DataSourceDestination(dataSource), operation); 053 * dbSetupTracker.launchIfNecessary(dbSetup); 054 * } 055 * 056 * @Test 057 * public void readOnlyTest1() { 058 * dbSetupTracker.skipNextLaunch(); 059 * ... 060 * } 061 * 062 * @Test 063 * public void readOnlyTest2() { 064 * dbSetupTracker.skipNextLaunch(); 065 * ... 066 * } 067 * 068 * @Test 069 * public void readOnlyTest3() { 070 * dbSetupTracker.skipNextLaunch(); 071 * ... 072 * } 073 * 074 * @Test 075 * public void readWriteTest1() { 076 * // No call to dbSetupTracker.skipNextLaunch(); 077 * ... 078 * } 079 * </pre> 080 * @author JB Nizet 081 */ 082 public final class DbSetupTracker { 083 private DbSetup lastSetupLaunched; 084 private boolean nextLaunchSkipped; 085 086 /** 087 * Executes the given DbSetup unless all the following conditions are <code>true</code>: 088 * <ul> 089 * <li>{@link #skipNextLaunch()} has been called since the last call to this method;</li> 090 * <li>the given <code>dbSetup</code> is equal to the last DbSetup launched by this method</li> 091 * </ul> 092 * This method resets the <code>skipNextLaunch</code> flag to <code>false</code>. 093 * @param dbSetup the DbSetup to execute (or skip) 094 */ 095 public void launchIfNecessary(@Nonnull DbSetup dbSetup) { 096 boolean skipLaunch = nextLaunchSkipped && dbSetup.equals(lastSetupLaunched); 097 nextLaunchSkipped = false; 098 if (skipLaunch) { 099 return; 100 } 101 dbSetup.launch(); 102 lastSetupLaunched = dbSetup; 103 } 104 105 /** 106 * Marks the current test method as read-only, and thus the need for the next test method to re-execute the same 107 * sequence of database setup operations. 108 */ 109 public void skipNextLaunch() { 110 this.nextLaunchSkipped = true; 111 } 112 113 @Override 114 public String toString() { 115 return "DbSetupTracker [lastSetupLaunched=" 116 + lastSetupLaunched 117 + ", nextLaunchSkipped=" 118 + nextLaunchSkipped 119 + "]"; 120 } 121 }