Introduce @SqlConfig for common SQL script config
Prior to this commit, @Sql provided attributes for configuring the syntax of the referenced SQL scripts as well as exception handling and transaction behavior; however, such configuration could not be reused across @Sql declarations thus requiring developers to copy-and-paste common configuration and resulting in unnecessary code duplication. This commit addresses this issue by introducing a new @SqlConfig annotation that can be used to declare common, global configuration for SQL scripts that can be reused within a test class hierarchy. - Introduced top-level @SqlConfig annotation and extracted common configuration attributes from @Sql. - @SqlConfig can be used at the class level for common, global config or via the new 'config' attribute of @Sql for local config. - Introduced MergedSqlConfig as a holder for the merged values from local and global @SqlConfig instances. MergedSqlConfig also contains the logic for overriding global configuration with local configuration. - Refactored all attributes of @SqlConfig to be either of type String or custom enums in order to support overriding. Empty Strings or DEFAULT enum values imply the use of a default or inherited value. Issue: SPR-11896
This commit is contained in:
@@ -25,7 +25,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for custom SQL script syntax
|
||||
* configured via {@link Sql @Sql}.
|
||||
* configured via {@link SqlConfig @SqlConfig}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
@@ -35,16 +35,9 @@ import static org.junit.Assert.*;
|
||||
public class CustomScriptSyntaxSqlScriptsTests extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
|
||||
@Test
|
||||
@SqlGroup({//
|
||||
@Sql("schema.sql"),//
|
||||
@Sql(//
|
||||
scripts = "data-add-users-with-custom-script-syntax.sql",//
|
||||
commentPrefix = "`",//
|
||||
blockCommentStartDelimiter = "#$",//
|
||||
blockCommentEndDelimiter = "$#",//
|
||||
separator = "@@"//
|
||||
) //
|
||||
})
|
||||
@Sql("schema.sql")
|
||||
@Sql(scripts = "data-add-users-with-custom-script-syntax.sql",//
|
||||
config = @SqlConfig(commentPrefix = "`", blockCommentStartDelimiter = "#$", blockCommentEndDelimiter = "$#", separator = "@@"))
|
||||
public void methodLevelScripts() {
|
||||
assertNumUsers(3);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.context.jdbc;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Modified copy of {@link CustomScriptSyntaxSqlScriptsTests} with
|
||||
* {@link SqlConfig @SqlConfig} defined at the class level.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
@ContextConfiguration(classes = EmptyDatabaseConfig.class)
|
||||
@DirtiesContext
|
||||
@SqlConfig(commentPrefix = "`", blockCommentStartDelimiter = "#$", blockCommentEndDelimiter = "$#", separator = "@@")
|
||||
public class GlobalCustomScriptSyntaxSqlScriptsTests extends AbstractTransactionalJUnit4SpringContextTests {
|
||||
|
||||
@Test
|
||||
@Sql(scripts = "schema.sql", config = @SqlConfig(separator = ";"))
|
||||
@Sql("data-add-users-with-custom-script-syntax.sql")
|
||||
public void methodLevelScripts() {
|
||||
assertNumUsers(3);
|
||||
}
|
||||
|
||||
protected void assertNumUsers(int expected) {
|
||||
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.test.context.jdbc;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.jdbc.datasource.init.ScriptUtils.*;
|
||||
import static org.springframework.test.context.jdbc.SqlConfig.ErrorMode.*;
|
||||
import static org.springframework.test.context.jdbc.SqlConfig.TransactionMode.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MergedSqlConfig}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public class MergedSqlConfigTests {
|
||||
|
||||
private void assertDefaults(MergedSqlConfig cfg) {
|
||||
assertNotNull(cfg);
|
||||
assertEquals("dataSource", "", cfg.getDataSource());
|
||||
assertEquals("transactionManager", "", cfg.getTransactionManager());
|
||||
assertEquals("transactionMode", INFERRED, cfg.getTransactionMode());
|
||||
assertEquals("encoding", "", cfg.getEncoding());
|
||||
assertEquals("separator", DEFAULT_STATEMENT_SEPARATOR, cfg.getSeparator());
|
||||
assertEquals("commentPrefix", DEFAULT_COMMENT_PREFIX, cfg.getCommentPrefix());
|
||||
assertEquals("blockCommentStartDelimiter", DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
||||
cfg.getBlockCommentStartDelimiter());
|
||||
assertEquals("blockCommentEndDelimiter", DEFAULT_BLOCK_COMMENT_END_DELIMITER, cfg.getBlockCommentEndDelimiter());
|
||||
assertEquals("errorMode", FAIL_ON_ERROR, cfg.getErrorMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void localConfigWithDefaults() throws Exception {
|
||||
Method method = getClass().getMethod("localConfigMethodWithDefaults");
|
||||
SqlConfig localSqlConfig = method.getAnnotation(Sql.class).config();
|
||||
MergedSqlConfig cfg = new MergedSqlConfig(localSqlConfig, getClass());
|
||||
assertDefaults(cfg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void globalConfigWithDefaults() throws Exception {
|
||||
Method method = GlobalConfigWithDefaultsClass.class.getMethod("globalConfigMethod");
|
||||
SqlConfig localSqlConfig = method.getAnnotation(Sql.class).config();
|
||||
MergedSqlConfig cfg = new MergedSqlConfig(localSqlConfig, GlobalConfigWithDefaultsClass.class);
|
||||
assertDefaults(cfg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void localConfigWithCustomValues() throws Exception {
|
||||
Method method = getClass().getMethod("localConfigMethodWithCustomValues");
|
||||
SqlConfig localSqlConfig = method.getAnnotation(Sql.class).config();
|
||||
MergedSqlConfig cfg = new MergedSqlConfig(localSqlConfig, getClass());
|
||||
assertNotNull(cfg);
|
||||
assertEquals("dataSource", "ds", cfg.getDataSource());
|
||||
assertEquals("transactionManager", "txMgr", cfg.getTransactionManager());
|
||||
assertEquals("transactionMode", ISOLATED, cfg.getTransactionMode());
|
||||
assertEquals("encoding", "enigma", cfg.getEncoding());
|
||||
assertEquals("separator", "\n", cfg.getSeparator());
|
||||
assertEquals("commentPrefix", "`", cfg.getCommentPrefix());
|
||||
assertEquals("blockCommentStartDelimiter", "<<", cfg.getBlockCommentStartDelimiter());
|
||||
assertEquals("blockCommentEndDelimiter", ">>", cfg.getBlockCommentEndDelimiter());
|
||||
assertEquals("errorMode", IGNORE_FAILED_DROPS, cfg.getErrorMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void localConfigWithContinueOnError() throws Exception {
|
||||
Method method = getClass().getMethod("localConfigMethodWithContinueOnError");
|
||||
SqlConfig localSqlConfig = method.getAnnotation(Sql.class).config();
|
||||
MergedSqlConfig cfg = new MergedSqlConfig(localSqlConfig, getClass());
|
||||
assertNotNull(cfg);
|
||||
assertEquals("errorMode", CONTINUE_ON_ERROR, cfg.getErrorMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void localConfigWithIgnoreFailedDrops() throws Exception {
|
||||
Method method = getClass().getMethod("localConfigMethodWithIgnoreFailedDrops");
|
||||
SqlConfig localSqlConfig = method.getAnnotation(Sql.class).config();
|
||||
MergedSqlConfig cfg = new MergedSqlConfig(localSqlConfig, getClass());
|
||||
assertNotNull(cfg);
|
||||
assertEquals("errorMode", IGNORE_FAILED_DROPS, cfg.getErrorMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void globalConfig() throws Exception {
|
||||
Method method = GlobalConfigClass.class.getMethod("globalConfigMethod");
|
||||
SqlConfig localSqlConfig = method.getAnnotation(Sql.class).config();
|
||||
MergedSqlConfig cfg = new MergedSqlConfig(localSqlConfig, GlobalConfigClass.class);
|
||||
assertNotNull(cfg);
|
||||
assertEquals("dataSource", "", cfg.getDataSource());
|
||||
assertEquals("transactionManager", "", cfg.getTransactionManager());
|
||||
assertEquals("transactionMode", INFERRED, cfg.getTransactionMode());
|
||||
assertEquals("encoding", "global", cfg.getEncoding());
|
||||
assertEquals("separator", "\n", cfg.getSeparator());
|
||||
assertEquals("commentPrefix", DEFAULT_COMMENT_PREFIX, cfg.getCommentPrefix());
|
||||
assertEquals("blockCommentStartDelimiter", DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
||||
cfg.getBlockCommentStartDelimiter());
|
||||
assertEquals("blockCommentEndDelimiter", DEFAULT_BLOCK_COMMENT_END_DELIMITER, cfg.getBlockCommentEndDelimiter());
|
||||
assertEquals("errorMode", IGNORE_FAILED_DROPS, cfg.getErrorMode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void globalConfigWithLocalOverrides() throws Exception {
|
||||
Method method = GlobalConfigClass.class.getMethod("globalConfigWithLocalOverridesMethod");
|
||||
SqlConfig localSqlConfig = method.getAnnotation(Sql.class).config();
|
||||
MergedSqlConfig cfg = new MergedSqlConfig(localSqlConfig, GlobalConfigClass.class);
|
||||
|
||||
assertNotNull(cfg);
|
||||
assertEquals("dataSource", "", cfg.getDataSource());
|
||||
assertEquals("transactionManager", "", cfg.getTransactionManager());
|
||||
assertEquals("transactionMode", INFERRED, cfg.getTransactionMode());
|
||||
assertEquals("encoding", "local", cfg.getEncoding());
|
||||
assertEquals("separator", "@@", cfg.getSeparator());
|
||||
assertEquals("commentPrefix", DEFAULT_COMMENT_PREFIX, cfg.getCommentPrefix());
|
||||
assertEquals("blockCommentStartDelimiter", DEFAULT_BLOCK_COMMENT_START_DELIMITER,
|
||||
cfg.getBlockCommentStartDelimiter());
|
||||
assertEquals("blockCommentEndDelimiter", DEFAULT_BLOCK_COMMENT_END_DELIMITER, cfg.getBlockCommentEndDelimiter());
|
||||
assertEquals("errorMode", CONTINUE_ON_ERROR, cfg.getErrorMode());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Sql
|
||||
public static void localConfigMethodWithDefaults() {
|
||||
}
|
||||
|
||||
@Sql(config = @SqlConfig(dataSource = "ds", transactionManager = "txMgr", transactionMode = ISOLATED, encoding = "enigma", separator = "\n", commentPrefix = "`", blockCommentStartDelimiter = "<<", blockCommentEndDelimiter = ">>", errorMode = IGNORE_FAILED_DROPS))
|
||||
public static void localConfigMethodWithCustomValues() {
|
||||
}
|
||||
|
||||
@Sql(config = @SqlConfig(errorMode = CONTINUE_ON_ERROR))
|
||||
public static void localConfigMethodWithContinueOnError() {
|
||||
}
|
||||
|
||||
@Sql(config = @SqlConfig(errorMode = IGNORE_FAILED_DROPS))
|
||||
public static void localConfigMethodWithIgnoreFailedDrops() {
|
||||
}
|
||||
|
||||
|
||||
@SqlConfig
|
||||
public static class GlobalConfigWithDefaultsClass {
|
||||
|
||||
@Sql("foo.sql")
|
||||
public void globalConfigMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
@SqlConfig(encoding = "global", separator = "\n", errorMode = IGNORE_FAILED_DROPS)
|
||||
public static class GlobalConfigClass {
|
||||
|
||||
@Sql("foo.sql")
|
||||
public void globalConfigMethod() {
|
||||
}
|
||||
|
||||
@Sql(scripts = "foo.sql", config = @SqlConfig(encoding = "local", separator = "@@", errorMode = CONTINUE_ON_ERROR))
|
||||
public void globalConfigWithLocalOverridesMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,6 +40,7 @@ import static org.junit.Assert.*;
|
||||
/**
|
||||
* Integration tests for {@link Sql @Sql} that verify support for multiple
|
||||
* {@link DataSource}s and {@link PlatformTransactionManager}s.
|
||||
* <p>Simultaneously tests for method-level overrides via {@code @SqlConfig}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
@@ -48,6 +49,7 @@ import static org.junit.Assert.*;
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@DirtiesContext
|
||||
@SqlConfig(dataSource = "dataSource1", transactionManager = "txMgr1")
|
||||
public class MultipleDataSourcesAndTransactionManagersSqlScriptsTests {
|
||||
|
||||
@Autowired
|
||||
@@ -58,13 +60,13 @@ public class MultipleDataSourcesAndTransactionManagersSqlScriptsTests {
|
||||
|
||||
|
||||
@Test
|
||||
@Sql(scripts = "data-add-dogbert.sql", dataSource = "dataSource1", transactionManager = "txMgr1")
|
||||
@Sql("data-add-dogbert.sql")
|
||||
public void database1() {
|
||||
assertUsers(new JdbcTemplate(dataSource1), "Dilbert", "Dogbert");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Sql(scripts = "data-add-catbert.sql", dataSource = "dataSource2", transactionManager = "txMgr2")
|
||||
@Sql(scripts = "data-add-catbert.sql", config = @SqlConfig(dataSource = "dataSource2", transactionManager = "txMgr2"))
|
||||
public void database2() {
|
||||
assertUsers(new JdbcTemplate(dataSource2), "Dilbert", "Catbert");
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ import static org.junit.Assert.*;
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@DirtiesContext
|
||||
@Transactional("txMgr1")
|
||||
@SqlConfig(dataSource = "dataSource1", transactionManager = "txMgr1")
|
||||
public class MultipleDataSourcesAndTransactionManagersTransactionalSqlScriptsTests {
|
||||
|
||||
@Autowired
|
||||
@@ -58,15 +60,14 @@ public class MultipleDataSourcesAndTransactionManagersTransactionalSqlScriptsTes
|
||||
|
||||
|
||||
@Test
|
||||
@Transactional("txMgr1")
|
||||
@Sql(scripts = "data-add-dogbert.sql", dataSource = "dataSource1", transactionManager = "txMgr1")
|
||||
@Sql("data-add-dogbert.sql")
|
||||
public void database1() {
|
||||
assertUsers(new JdbcTemplate(dataSource1), "Dilbert", "Dogbert");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional("txMgr2")
|
||||
@Sql(scripts = "data-add-catbert.sql", dataSource = "dataSource2", transactionManager = "txMgr2")
|
||||
@Sql(scripts = "data-add-catbert.sql", config = @SqlConfig(dataSource = "dataSource2", transactionManager = "txMgr2"))
|
||||
public void database2() {
|
||||
assertUsers(new JdbcTemplate(dataSource2), "Dilbert", "Catbert");
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.test.context.jdbc;
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.jdbc.SqlConfig.TransactionMode;
|
||||
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
|
||||
import org.springframework.test.context.transaction.AfterTransaction;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
@@ -27,7 +28,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Transactional integration tests that verify commit semantics for
|
||||
* {@link Sql#requireNewTransaction}.
|
||||
* {@link SqlConfig#requireNewTransaction}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
@@ -42,7 +43,7 @@ public class RequiresNewTransactionSqlScriptsTests extends AbstractTransactional
|
||||
}
|
||||
|
||||
@Test
|
||||
@SqlGroup(@Sql(scripts = "data-add-dogbert.sql", requireNewTransaction = true))
|
||||
@SqlGroup(@Sql(scripts = "data-add-dogbert.sql", config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)))
|
||||
public void methodLevelScripts() {
|
||||
assertNumUsers(1);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class TransactionalAfterTestMethodSqlScriptsTests extends AbstractTransac
|
||||
|
||||
@Test
|
||||
@SqlGroup({//
|
||||
@Sql({ "schema.sql", "data.sql" }),//
|
||||
@Sql({ "schema.sql", "data.sql" }),//
|
||||
@Sql(scripts = "drop-schema.sql", executionPhase = AFTER_TEST_METHOD) //
|
||||
})
|
||||
// test## is required for @FixMethodOrder.
|
||||
|
||||
Reference in New Issue
Block a user