diff --git a/spring-test/src/test/java/org/springframework/test/context/testng/transaction/programmatic/ProgrammaticTxMgmtTestNGTests.java b/spring-test/src/test/java/org/springframework/test/context/testng/transaction/programmatic/ProgrammaticTxMgmtTestNGTests.java new file mode 100644 index 0000000000..8a91d9f878 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/testng/transaction/programmatic/ProgrammaticTxMgmtTestNGTests.java @@ -0,0 +1,289 @@ +/* + * 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.testng.transaction.programmatic; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +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.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; +import org.springframework.test.context.transaction.AfterTransaction; +import org.springframework.test.context.transaction.BeforeTransaction; +import org.springframework.test.context.transaction.TestTransaction; +import org.springframework.test.context.transaction.programmatic.ProgrammaticTxMgmtTests; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.testng.IHookCallBack; +import org.testng.ITestResult; +import org.testng.annotations.Test; + +import static org.junit.Assert.*; +import static org.springframework.test.transaction.TransactionTestUtils.*; + +/** + * This class is a copy of {@link ProgrammaticTxMgmtTests} that has been modified + * to run with TestNG. + * + * @author Sam Brannen + * @since 4.1 + */ +@ContextConfiguration +public class ProgrammaticTxMgmtTestNGTests extends AbstractTransactionalTestNGSpringContextTests { + + private String testName; + + + @Override + public void run(IHookCallBack callBack, ITestResult testResult) { + this.testName = testResult.getMethod().getMethodName(); + super.run(callBack, testResult); + } + + @BeforeTransaction + public void beforeTransaction() { + deleteFromTables("user"); + executeSqlScript("classpath:/org/springframework/test/context/jdbc/data.sql", false); + } + + @AfterTransaction + public void afterTransaction() { + switch (testName) { + case "commitTxAndStartNewTx": { + assertUsers("Dogbert"); + break; + } + case "commitTxButDoNotStartNewTx": { + assertUsers("Dogbert"); + break; + } + case "rollbackTxAndStartNewTx": { + assertUsers("Dilbert"); + break; + } + case "rollbackTxButDoNotStartNewTx": { + assertUsers("Dilbert"); + break; + } + case "rollbackTxAndStartNewTxWithDefaultCommitSemantics": { + assertUsers("Dilbert", "Dogbert"); + break; + } + case "startTxWithExistingTransaction": { + assertUsers("Dilbert"); + break; + } + default: { + fail("missing 'after transaction' assertion for test method: " + testName); + } + } + } + + @Test + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public void isActiveWithNonExistentTransactionContext() { + assertFalse(TestTransaction.isActive()); + } + + @Test(expectedExceptions = IllegalStateException.class) + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public void flagForRollbackWithNonExistentTransactionContext() { + TestTransaction.flagForRollback(); + } + + @Test(expectedExceptions = IllegalStateException.class) + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public void flagForCommitWithNonExistentTransactionContext() { + TestTransaction.flagForCommit(); + } + + @Test(expectedExceptions = IllegalStateException.class) + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public void isFlaggedForRollbackWithNonExistentTransactionContext() { + TestTransaction.isFlaggedForRollback(); + } + + @Test(expectedExceptions = IllegalStateException.class) + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public void startTxWithNonExistentTransactionContext() { + TestTransaction.start(); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void startTxWithExistingTransaction() { + TestTransaction.start(); + } + + @Test(expectedExceptions = IllegalStateException.class) + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public void endTxWithNonExistentTransactionContext() { + TestTransaction.end(); + } + + @Test + public void commitTxAndStartNewTx() { + assertInTransaction(true); + assertTrue(TestTransaction.isActive()); + assertUsers("Dilbert"); + deleteFromTables("user"); + assertUsers(); + + // Commit + TestTransaction.flagForCommit(); + assertFalse(TestTransaction.isFlaggedForRollback()); + TestTransaction.end(); + assertInTransaction(false); + assertFalse(TestTransaction.isActive()); + assertUsers(); + + executeSqlScript("classpath:/org/springframework/test/context/jdbc/data-add-dogbert.sql", false); + assertUsers("Dogbert"); + + TestTransaction.start(); + assertInTransaction(true); + assertTrue(TestTransaction.isActive()); + } + + @Test + public void commitTxButDoNotStartNewTx() { + assertInTransaction(true); + assertTrue(TestTransaction.isActive()); + assertUsers("Dilbert"); + deleteFromTables("user"); + assertUsers(); + + // Commit + TestTransaction.flagForCommit(); + assertFalse(TestTransaction.isFlaggedForRollback()); + TestTransaction.end(); + assertFalse(TestTransaction.isActive()); + assertInTransaction(false); + assertUsers(); + + executeSqlScript("classpath:/org/springframework/test/context/jdbc/data-add-dogbert.sql", false); + assertUsers("Dogbert"); + } + + @Test + public void rollbackTxAndStartNewTx() { + assertInTransaction(true); + assertTrue(TestTransaction.isActive()); + assertUsers("Dilbert"); + deleteFromTables("user"); + assertUsers(); + + // Rollback (automatically) + assertTrue(TestTransaction.isFlaggedForRollback()); + TestTransaction.end(); + assertFalse(TestTransaction.isActive()); + assertInTransaction(false); + assertUsers("Dilbert"); + + // Start new transaction with default rollback semantics + TestTransaction.start(); + assertInTransaction(true); + assertTrue(TestTransaction.isFlaggedForRollback()); + assertTrue(TestTransaction.isActive()); + + executeSqlScript("classpath:/org/springframework/test/context/jdbc/data-add-dogbert.sql", false); + assertUsers("Dilbert", "Dogbert"); + } + + @Test + public void rollbackTxButDoNotStartNewTx() { + assertInTransaction(true); + assertTrue(TestTransaction.isActive()); + assertUsers("Dilbert"); + deleteFromTables("user"); + assertUsers(); + + // Rollback (automatically) + assertTrue(TestTransaction.isFlaggedForRollback()); + TestTransaction.end(); + assertFalse(TestTransaction.isActive()); + assertInTransaction(false); + assertUsers("Dilbert"); + } + + @Test + @Rollback(false) + public void rollbackTxAndStartNewTxWithDefaultCommitSemantics() { + assertInTransaction(true); + assertTrue(TestTransaction.isActive()); + assertUsers("Dilbert"); + deleteFromTables("user"); + assertUsers(); + + // Rollback + TestTransaction.flagForRollback(); + assertTrue(TestTransaction.isFlaggedForRollback()); + TestTransaction.end(); + assertFalse(TestTransaction.isActive()); + assertInTransaction(false); + assertUsers("Dilbert"); + + // Start new transaction with default commit semantics + TestTransaction.start(); + assertInTransaction(true); + assertFalse(TestTransaction.isFlaggedForRollback()); + assertTrue(TestTransaction.isActive()); + + executeSqlScript("classpath:/org/springframework/test/context/jdbc/data-add-dogbert.sql", false); + assertUsers("Dilbert", "Dogbert"); + } + + // ------------------------------------------------------------------------- + + private void assertUsers(String... users) { + List> results = jdbcTemplate.queryForList("select name from user"); + List names = new ArrayList(); + for (Map map : results) { + names.add((String) map.get("name")); + } + assertEquals(Arrays.asList(users), names); + } + + + // ------------------------------------------------------------------------- + + @Configuration + static class Config { + + @Bean + public PlatformTransactionManager transactionManager() { + return new DataSourceTransactionManager(dataSource()); + } + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder()// + .setName("programmatic-tx-mgmt-test-db")// + .addScript("classpath:/org/springframework/test/context/jdbc/schema.sql") // + .build(); + } + } + +}