Introduce annotation to execute SQL scripts in the TCF

Prior to this commit, it was possible to execute SQL scripts
programmatically via ResourceDatabasePopulator, JdbcTestUtils, and
ScriptUtils. Furthermore, it was also possible to execute SQL scripts
declaratively via the <jdbc> XML namespace. However, it was not
possible to execute SQL scripts declaratively on a per test class or
per test method basis.

This commit makes it possible to declaratively configure SQL scripts
for execution in integration tests via annotations that can be declared
at the class or method level. Details follow.

 - Introduced a repeatable @DatabaseInitializer annotation that can be
   used to configure SQL scripts at the class or method level with
   method-level overrides. @DatabaseInitializers serves as a container
   for @DatabaseInitializer.

 - Introduced a new DatabaseInitializerTestExecutionListener that is
   responsible for parsing @DatabaseInitializer and
   @DatabaseInitializers and executing SQL scripts.

 - DatabaseInitializerTestExecutionListener is registered by default in
   abstract base test classes as well as in TestContextBootstrapper
   implementations.

 - @DatabaseInitializer and @DatabaseInitializers may be used as
   meta-annotations; however, attribute overrides are not currently
   supported for repeatable annotations used as meta-annotations. This
   is a known limitation of Spring's AnnotationUtils.

 - The semantics for locating SQL script resources is consistent with
   @ContextConfiguration's semantics for locating XML configuration
   files. In addition, a default SQL script can be detected based
   either on the name of the annotated class or on the name of the
   annotated test method.

 - @DatabaseInitializer allows for specifying which DataSource and
   PlatformTransactionManager to use from the test's
   ApplicationContext, including default conventions consistent with
   TransactionalTestExecutionListener and @TransactionConfiguration.

 - @DatabaseInitializer supports all of the script configuration options
   currently supported by ResourceDatabasePopulator.

 - @DatabaseInitializer and DatabaseInitializerTestExecutionListener
   support execution phases for scripts that dictate when SQL scripts
   are executed (i.e., before or after a test method).

 - SQL scripts can be executed within the current test's transaction if
   present, outside of the current test's transaction if present, or
   always in a new transaction, depending on the value of the boolean
   requireNewTransaction flag in @DatabaseInitializer.

 - DatabaseInitializerTestExecutionListener delegates to
   ResourceDatabasePopulator#execute to actually execute the scripts.

Issue: SPR-7655
This commit is contained in:
Sam Brannen
2014-05-27 23:49:49 +02:00
parent 8fb0f5c7d1
commit 5fd6ebb548
37 changed files with 1912 additions and 128 deletions

View File

@@ -45,7 +45,7 @@ public class TestExecutionListenersTests {
@Test
public void verifyNumDefaultListenersRegistered() throws Exception {
TestContextManager testContextManager = new TestContextManager(DefaultListenersExampleTestCase.class);
assertEquals("Num registered TELs for DefaultListenersExampleTestCase.", 3,
assertEquals("Num registered TELs for DefaultListenersExampleTestCase.", 4,
testContextManager.getTestExecutionListeners().size());
}

View File

@@ -0,0 +1,56 @@
/*
* 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.*;
/**
* Integration tests that verify support for custom SQL script syntax
* configured via {@link DatabaseInitializer @DatabaseInitializer}.
*
* @author Sam Brannen
* @since 4.1
*/
@ContextConfiguration(classes = EmptyDatabaseConfig.class)
@DirtiesContext
public class CustomScriptSyntaxDatabaseInitializerTests extends AbstractTransactionalJUnit4SpringContextTests {
@Test
@DatabaseInitializers({//
@DatabaseInitializer("schema.sql"),//
@DatabaseInitializer(//
scripts = "data-add-users-with-custom-script-syntax.sql",//
commentPrefix = "`",//
blockCommentStartDelimiter = "#$",//
blockCommentEndDelimiter = "$#",//
separator = "@@"//
) //
})
public void methodLevelScripts() {
assertNumUsers(3);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
}
}

View File

@@ -0,0 +1,100 @@
/*
* 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.mockito.Mockito;
import org.springframework.test.context.TestContext;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* Unit tests for {@link DatabaseInitializerTestExecutionListener}.
*
* @author Sam Brannen
* @since 4.1
*/
public class DatabaseInitializerTestExecutionListenerTests {
private final DatabaseInitializerTestExecutionListener listener = new DatabaseInitializerTestExecutionListener();
private final TestContext testContext = mock(TestContext.class);
@Test
public void missingValueAndScriptsAtClassLevel() throws Exception {
Class<?> clazz = MissingValueAndScriptsAtClassLevel.class;
Mockito.<Class<?>> when(testContext.getTestClass()).thenReturn(clazz);
when(testContext.getTestMethod()).thenReturn(clazz.getDeclaredMethod("foo"));
assertExceptionContains(clazz.getSimpleName() + ".sql");
}
@Test
public void missingValueAndScriptsAtMethodLevel() throws Exception {
Class<?> clazz = MissingValueAndScriptsAtMethodLevel.class;
Mockito.<Class<?>> when(testContext.getTestClass()).thenReturn(clazz);
when(testContext.getTestMethod()).thenReturn(clazz.getDeclaredMethod("foo"));
assertExceptionContains(clazz.getSimpleName() + ".foo" + ".sql");
}
@Test
public void valueAndScriptsDeclared() throws Exception {
Class<?> clazz = ValueAndScriptsDeclared.class;
Mockito.<Class<?>> when(testContext.getTestClass()).thenReturn(clazz);
when(testContext.getTestMethod()).thenReturn(clazz.getDeclaredMethod("valueAndScriptsDeclared"));
assertExceptionContains("Only one declaration of SQL script paths is permitted");
}
private void assertExceptionContains(String msg) throws Exception {
try {
listener.beforeTestMethod(testContext);
fail("Should have thrown an IllegalStateException.");
}
catch (IllegalStateException e) {
assertTrue("Exception message should contain: " + msg, e.getMessage().contains(msg));
}
}
// -------------------------------------------------------------------------
@DatabaseInitializer
static class MissingValueAndScriptsAtClassLevel {
public void foo() {
}
}
static class MissingValueAndScriptsAtMethodLevel {
@DatabaseInitializer
public void foo() {
}
}
static class ValueAndScriptsDeclared {
@DatabaseInitializer(value = "foo", scripts = "bar")
public void valueAndScriptsDeclared() {
}
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.*;
/**
* Integration tests that verify support for default SQL script detection.
*
* @author Sam Brannen
* @since 4.1
*/
@ContextConfiguration(classes = EmptyDatabaseConfig.class)
@DatabaseInitializer
@DirtiesContext
public class DefaultScriptDetectionDatabaseInitializerTests extends AbstractTransactionalJUnit4SpringContextTests {
@Test
public void classLevel() {
assertNumUsers(2);
}
@Test
@DatabaseInitializer
public void methodLevel() {
assertNumUsers(3);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
}
}

View File

@@ -0,0 +1,10 @@
DROP TABLE user IF EXISTS;
CREATE TABLE user (
name VARCHAR(20) NOT NULL,
PRIMARY KEY(name)
);
INSERT INTO user VALUES('Dilbert');
INSERT INTO user VALUES('Dogbert');
INSERT INTO user VALUES('Catbert');

View File

@@ -0,0 +1,9 @@
DROP TABLE user IF EXISTS;
CREATE TABLE user (
name VARCHAR(20) NOT NULL,
PRIMARY KEY(name)
);
INSERT INTO user VALUES('Dilbert');
INSERT INTO user VALUES('Dogbert');

View File

@@ -0,0 +1,46 @@
/*
* 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 javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.transaction.PlatformTransactionManager;
/**
* Empty database configuration class for SQL script integration tests.
*
* @author Sam Brannen
* @since 4.1
*/
@Configuration
public class EmptyDatabaseConfig {
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().build();
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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.annotation.Retention;
import java.lang.annotation.Target;
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 java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import static org.junit.Assert.*;
/**
* Integration tests that verify support for using
* {@link DatabaseInitializer @DatabaseInitializer} and
* {@link DatabaseInitializers @DatabaseInitializers} as a meta-annotations.
*
* @author Sam Brannen
* @since 4.1
*/
@ContextConfiguration(classes = EmptyDatabaseConfig.class)
@DirtiesContext
public class MetaAnnotationDatabaseInitializerTests extends AbstractTransactionalJUnit4SpringContextTests {
@Test
@MetaDbInitializer
public void metaDatabaseInitializer() {
assertNumUsers(1);
}
@Test
@MetaDbInitializers
public void metaDatabaseInitializers() {
assertNumUsers(1);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
}
@DatabaseInitializer({ "drop-schema.sql", "schema.sql", "data.sql" })
@Retention(RUNTIME)
@Target(METHOD)
static @interface MetaDbInitializer {
}
@DatabaseInitializers({//
@DatabaseInitializer("drop-schema.sql"),//
@DatabaseInitializer("schema.sql"),//
@DatabaseInitializer("data.sql") //
})
@Retention(RUNTIME)
@Target(METHOD)
static @interface MetaDbInitializers {
}
}

View File

@@ -0,0 +1,110 @@
/*
* 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 javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
import static org.junit.Assert.*;
/**
* Integration tests for {@link DatabaseInitializer @DatabaseInitializer} that
* verify support for multiple {@link DataSource}s and {@link PlatformTransactionManager}s.
*
* @author Sam Brannen
* @since 4.1
* @see MultipleDataSourcesAndTransactionManagersTransactionalDatabaseInitializerTests
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class MultipleDataSourcesAndTransactionManagersDatabaseInitializerTests {
@Autowired
private DataSource dataSource1;
@Autowired
private DataSource dataSource2;
@Test
@DatabaseInitializer(scripts = "data-add-dogbert.sql", dataSource = "dataSource1", transactionManager = "txMgr1")
public void database1() {
assertUsersExist(new JdbcTemplate(dataSource1), "Dilbert", "Dogbert");
}
@Test
@DatabaseInitializer(scripts = "data-add-catbert.sql", dataSource = "dataSource2", transactionManager = "txMgr2")
public void database2() {
assertUsersExist(new JdbcTemplate(dataSource2), "Dilbert", "Catbert");
}
private void assertUsersExist(JdbcTemplate jdbcTemplate, String... users) {
String query = "select count(name) from user where name =?";
for (String user : users) {
assertTrue("User [" + user + "] must exist.",
jdbcTemplate.queryForObject(query, Integer.class, user).intValue() == 1);
}
}
@Configuration
static class Config {
@Bean
public PlatformTransactionManager txMgr1() {
return new DataSourceTransactionManager(dataSource1());
}
@Bean
public PlatformTransactionManager txMgr2() {
return new DataSourceTransactionManager(dataSource2());
}
@Bean
public DataSource dataSource1() {
return new EmbeddedDatabaseBuilder()//
.setName("database1")//
.addScript("classpath:/org/springframework/test/context/jdbc/schema.sql")//
.addScript("classpath:/org/springframework/test/context/jdbc/data.sql")//
.build();
}
@Bean
public DataSource dataSource2() {
return new EmbeddedDatabaseBuilder()//
.setName("database2")//
.addScript("classpath:/org/springframework/test/context/jdbc/schema.sql")//
.addScript("classpath:/org/springframework/test/context/jdbc/data.sql")//
.build();
}
}
}

View File

@@ -0,0 +1,112 @@
/*
* 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 javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.Assert.*;
/**
* Exact copy of {@link MultipleDataSourcesAndTransactionManagersDatabaseInitializerTests},
* except that the test methods are transactional.
*
* @author Sam Brannen
* @since 4.1
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@DirtiesContext
public class MultipleDataSourcesAndTransactionManagersTransactionalDatabaseInitializerTests {
@Autowired
private DataSource dataSource1;
@Autowired
private DataSource dataSource2;
@Test
@Transactional("txMgr1")
@DatabaseInitializer(scripts = "data-add-dogbert.sql", dataSource = "dataSource1", transactionManager = "txMgr1")
public void database1() {
assertUsersExist(new JdbcTemplate(dataSource1), "Dilbert", "Dogbert");
}
@Test
@Transactional("txMgr2")
@DatabaseInitializer(scripts = "data-add-catbert.sql", dataSource = "dataSource2", transactionManager = "txMgr2")
public void database2() {
assertUsersExist(new JdbcTemplate(dataSource2), "Dilbert", "Catbert");
}
private void assertUsersExist(JdbcTemplate jdbcTemplate, String... users) {
String query = "select count(name) from user where name =?";
for (String user : users) {
assertTrue("User [" + user + "] must exist.",
jdbcTemplate.queryForObject(query, Integer.class, user).intValue() == 1);
}
}
@Configuration
static class Config {
@Bean
public PlatformTransactionManager txMgr1() {
return new DataSourceTransactionManager(dataSource1());
}
@Bean
public PlatformTransactionManager txMgr2() {
return new DataSourceTransactionManager(dataSource2());
}
@Bean
public DataSource dataSource1() {
return new EmbeddedDatabaseBuilder()//
.setName("database1")//
.addScript("classpath:/org/springframework/test/context/jdbc/schema.sql")//
.addScript("classpath:/org/springframework/test/context/jdbc/data.sql")//
.build();
}
@Bean
public DataSource dataSource2() {
return new EmbeddedDatabaseBuilder()//
.setName("database2")//
.addScript("classpath:/org/springframework/test/context/jdbc/schema.sql")//
.addScript("classpath:/org/springframework/test/context/jdbc/data.sql")//
.build();
}
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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 javax.sql.DataSource;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.jdbc.JdbcTestUtils;
import static org.junit.Assert.*;
/**
* Integration tests which verify that scripts executed via
* {@link DatabaseInitializer @DatabaseInitializer} will persist between
* non-transactional test methods.
*
* @author Sam Brannen
* @since 4.1
*/
@RunWith(SpringJUnit4ClassRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ContextConfiguration(classes = EmptyDatabaseConfig.class)
@DatabaseInitializer({ "schema.sql", "data.sql" })
@DirtiesContext
public class NonTransactionalDatabaseInitializerTests {
protected JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Test
// test##_ prefix is required for @FixMethodOrder.
public void test01_classLevelScripts() {
assertNumUsers(1);
}
@Test
@DatabaseInitializers(@DatabaseInitializer("data-add-dogbert.sql"))
// test##_ prefix is required for @FixMethodOrder.
public void test02_methodLevelScripts() {
assertNumUsers(2);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected,
JdbcTestUtils.countRowsInTable(jdbcTemplate, "user"));
}
}

View File

@@ -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 javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.transaction.PlatformTransactionManager;
/**
* Database configuration class for SQL script integration tests with the 'user'
* table already created.
*
* @author Sam Brannen
* @since 4.1
*/
@Configuration
public class PopulatedSchemaDatabaseConfig {
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()//
.addScript("classpath:/org/springframework/test/context/jdbc/schema.sql") //
.build();
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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 org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.test.context.transaction.BeforeTransaction;
import static org.junit.Assert.*;
/**
* Transactional integration tests that verify rollback semantics for
* {@link DatabaseInitializer @DatabaseInitializer} support.
*
* @author Sam Brannen
* @since 4.1
*/
@ContextConfiguration(classes = PopulatedSchemaDatabaseConfig.class)
@DirtiesContext
public class PopulatedSchemaTransactionalDatabaseInitializerTests extends AbstractTransactionalJUnit4SpringContextTests {
@BeforeTransaction
@AfterTransaction
public void verifyPreAndPostTransactionDatabaseState() {
assertNumUsers(0);
}
@Test
@DatabaseInitializers(@DatabaseInitializer("data-add-dogbert.sql"))
public void methodLevelScripts() {
assertNumUsers(1);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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 org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.test.context.transaction.BeforeTransaction;
import static org.junit.Assert.*;
/**
* Transactional integration tests that verify commit semantics for
* {@link DatabaseInitializer#requireNewTransaction}.
*
* @author Sam Brannen
* @since 4.1
*/
@ContextConfiguration(classes = PopulatedSchemaDatabaseConfig.class)
@DirtiesContext
public class RequiresNewTransactionDatabaseInitializerTests extends AbstractTransactionalJUnit4SpringContextTests {
@BeforeTransaction
public void beforeTransaction() {
assertNumUsers(0);
}
@Test
@DatabaseInitializers(@DatabaseInitializer(scripts = "data-add-dogbert.sql", requireNewTransaction = true))
public void methodLevelScripts() {
assertNumUsers(1);
}
@AfterTransaction
public void afterTransaction() {
assertNumUsers(1);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.runners.MethodSorters;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.jdbc.DatabaseInitializer.ExecutionPhase;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.transaction.AfterTransaction;
import static org.junit.Assert.*;
/**
* Transactional integration tests for {@link DatabaseInitializer @DatabaseInitializer}
* that verify proper support for {@link ExecutionPhase#AFTER_TEST_METHOD}.
*
* @author Sam Brannen
* @since 4.1
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ContextConfiguration(classes = EmptyDatabaseConfig.class)
@DirtiesContext
public class TransactionalAfterTestMethodDatabaseInitializerTests extends AbstractTransactionalJUnit4SpringContextTests {
@Rule
public TestName testName = new TestName();
@AfterTransaction
public void afterTransaction() {
if ("test01".equals(testName.getMethodName())) {
try {
assertNumUsers(99);
fail("Should throw a BadSqlGrammarException after test01, assuming 'drop-schema.sql' was executed");
}
catch (BadSqlGrammarException e) {
/* expected */
}
}
}
@Test
@DatabaseInitializers({//
@DatabaseInitializer({ "schema.sql", "data.sql" }),//
@DatabaseInitializer(scripts = "drop-schema.sql", executionPhase = ExecutionPhase.AFTER_TEST_METHOD) //
})
// test## is required for @FixMethodOrder.
public void test01() {
assertNumUsers(1);
}
@Test
@DatabaseInitializers(@DatabaseInitializer({ "schema.sql", "data.sql", "data-add-dogbert.sql" }))
// test## is required for @FixMethodOrder.
public void test02() {
assertNumUsers(2);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import static org.junit.Assert.*;
/**
* Transactional integration tests for {@link DatabaseInitializer @DatabaseInitializer}
* support.
*
* @author Sam Brannen
* @since 4.1
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ContextConfiguration(classes = EmptyDatabaseConfig.class)
@DatabaseInitializers(@DatabaseInitializer({ "schema.sql", "data.sql" }))
@DirtiesContext
public class TransactionalDatabaseInitializerTests extends AbstractTransactionalJUnit4SpringContextTests {
@Test
// test##_ prefix is required for @FixMethodOrder.
public void test01_classLevelScripts() {
assertNumUsers(1);
}
@Test
@DatabaseInitializers(@DatabaseInitializer({ "drop-schema.sql", "schema.sql", "data.sql", "data-add-dogbert.sql" }))
// test##_ prefix is required for @FixMethodOrder.
public void test02_methodLevelScripts() {
assertNumUsers(2);
}
protected void assertNumUsers(int expected) {
assertEquals("Number of rows in the 'user' table.", expected, countRowsInTable("user"));
}
}

View File

@@ -0,0 +1 @@
INSERT INTO user VALUES('Catbert');

View File

@@ -0,0 +1 @@
INSERT INTO user VALUES('Dogbert');

View File

@@ -0,0 +1,22 @@
` custom single-line comment
#$ custom
block
comment
$#
INSERT
INTO
user
VALUES('Dilbert')
@@
` custom single-line comment
INSERT INTO user VALUES('Dogbert')@@
INSERT INTO user VALUES('Catbert')@@

View File

@@ -0,0 +1 @@
INSERT INTO user VALUES('Dilbert');

View File

@@ -0,0 +1 @@
DROP TABLE user IF EXISTS;

View File

@@ -0,0 +1,4 @@
CREATE TABLE user (
name VARCHAR(20) NOT NULL,
PRIMARY KEY(name)
);

View File

@@ -44,7 +44,7 @@ public class ContextLoaderUtilsMergedConfigTests extends AbstractContextLoaderUt
assertMergedConfig(
mergedConfig,
testClass,
new String[] { "classpath:/org/springframework/test/context/support/AbstractContextLoaderUtilsTests$BareAnnotations-context.xml" },
new String[] { "classpath:org/springframework/test/context/support/AbstractContextLoaderUtilsTests$BareAnnotations-context.xml" },
EMPTY_CLASS_ARRAY, DelegatingSmartContextLoader.class);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* 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.
@@ -96,7 +96,7 @@ public class GenericXmlContextLoaderResourceLocationsTests {
{
ClasspathExistentDefaultLocationsTestCase.class,
new String[] { "classpath:/org/springframework/test/context/support/GenericXmlContextLoaderResourceLocationsTests$1ClasspathExistentDefaultLocationsTestCase-context.xml" } },
new String[] { "classpath:org/springframework/test/context/support/GenericXmlContextLoaderResourceLocationsTests$1ClasspathExistentDefaultLocationsTestCase-context.xml" } },
{
ImplicitClasspathLocationsTestCase.class,

View File

@@ -192,13 +192,13 @@ public class TransactionalTestExecutionListenerTests {
@Test
public void retrieveConfigurationAttributesWithMissingTransactionConfiguration() throws Exception {
assertTransactionConfigurationAttributes(MissingTransactionConfigurationTestCase.class, "transactionManager",
assertTransactionConfigurationAttributes(MissingTransactionConfigurationTestCase.class, "",
true);
}
@Test
public void retrieveConfigurationAttributesWithEmptyTransactionConfiguration() throws Exception {
assertTransactionConfigurationAttributes(EmptyTransactionConfigurationTestCase.class, "transactionManager",
assertTransactionConfigurationAttributes(EmptyTransactionConfigurationTestCase.class, "",
true);
}