1 /*****************************************************************************
5 * Creation date 12 Oct 2012
8 *****************************************************************************/
10 package test.splat.common;
12 import java.util.List;
15 import javax.sql.DataSource;
17 import org.hibernate.SessionFactory;
18 import org.splat.log.AppLogger;
19 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.beans.factory.annotation.Qualifier;
21 import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
22 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
23 import org.springframework.orm.hibernate3.HibernateTemplate;
24 import org.springframework.test.context.ContextConfiguration;
25 import org.springframework.test.context.transaction.TransactionConfiguration;
26 import org.springframework.transaction.TransactionDefinition;
27 import org.springframework.transaction.TransactionStatus;
28 import org.springframework.transaction.support.DefaultTransactionDefinition;
29 import org.testng.Assert;
30 import org.testng.annotations.BeforeClass;
31 import org.testng.annotations.BeforeMethod;
32 import org.testng.annotations.Test;
35 * Base Siman Test class. Each test method is transactional by default.
36 * Use <code>NotTransactional</code> annotation to declare test method as not transactional.
37 * By default all operations on database are rolledback after each test method.
38 * To avoid this use <code>Rollback(false)</code> annotation.
40 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
44 @ContextConfiguration(locations = {
45 "/test/spring/ut-applicationContext.xml",
46 "/test/spring/ut-datasourceContext.xml",
47 "/spring/businessServiceContext.xml",
48 "/spring/daoContext.xml",
49 "/spring/globalContext.xml",
50 "/spring/technicalServiceContext.xml"
52 @TransactionConfiguration(defaultRollback = true, transactionManager = "txManager")
53 @Test(sequential=true, groups = {"service", "functional", "business"})
54 public class BaseTest extends TestListingAndOrder {
56 // ========================================= static methods
58 * Logger for the class.
60 private static final AppLogger LOG = AppLogger.getLogger(BaseTest.class);
63 * The helper class to work with hibernate session.
65 private HibernateTemplate _hibernateTemplate;
68 * Get the hibernateTemplate.
69 * @return the hibernateTemplate
71 @Test(enabled = false)
72 public HibernateTemplate getHibernateTemplate() {
73 return _hibernateTemplate;
76 // ======================================= static variables
80 * @see org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests#setDataSource(javax.sql.DataSource)
84 @Test(enabled = false)
85 // public void setDataSource(@Qualifier("p6spyiBatisDatasource")
86 @SuppressWarnings("deprecation")
87 public void setDataSource(@Qualifier("simanDatasource")
88 final DataSource dataSource) {
89 this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
93 * Set a hibernate session factory.
94 * @param aSessionFactory the hibernate session factory
97 @Test(enabled = false)
98 public void setSessionFactory(@Qualifier("simanSessionFactory") SessionFactory aSessionFactory) {
99 _hibernateTemplate = new HibernateTemplate(aSessionFactory);
103 * Method for the test data creation. It is called before the first test
107 public void initClass() {
109 // Initialize UserContext
110 // initUserContext();
112 } catch (Exception e) {
113 Assert.fail("Exception occured during the testing data creation. ", e);
119 * Insert base data before each method : matricule, department, language, reference.
122 public void insertBaseDataBeforeMethod() {
123 LOG.debug(" >>>>>>>>>>>>>>> COMMON - insertBaseDataBeforeMethod");
127 // [PRIVATE METHOD] ------------------------------
129 // [DATA PROVIDER METHOD : Insert / Select] ------------------------------
131 * Insert data for test : document.
134 // protected void insertData(final DocumentWithBLOBs document) {
135 // // Insert document
136 // _documentDAO.insert(document);
140 * Uses the current transaction to execute SQL statement in order to be able to
141 * see the current state of the database.
142 * @param statement the sql statement
144 @SuppressWarnings("deprecation")
145 protected void executeAndDisplaySqlStatement(final String statement) {
146 List<Map<String, Object>> resultSet = simpleJdbcTemplate.queryForList(statement);
147 displayResultset(resultSet);
151 * Uses the current transaction to execute SQL statement in order to be able to
152 * see the current state of the database.
153 * @param statement the sql statement
154 * @param args the sql statement parameters
156 @SuppressWarnings("deprecation")
157 protected void executeAndDisplaySqlStatement(final String statement, final Object...args) {
158 List<Map<String, Object>> resultSet = simpleJdbcTemplate.queryForList(statement, args);
159 displayResultset(resultSet);
163 * Displays resultset in log.
164 * @param resultSet the resultset to display.
166 private void displayResultset(final List<Map<String, Object>> resultSet) {
167 if(!resultSet.isEmpty()) {
168 Map<String, Object> firstElement = resultSet.get(0);
169 LOG.debug(firstElement.keySet().toString());
171 for (Map<String, Object> line : resultSet) {
172 StringBuilder logLine = new StringBuilder("[");
173 logLine.append(line.values());
175 LOG.debug(logLine.toString());
181 // ==========================================================================
182 // NESTED TRANSACTIONS MANAGEMENT
183 // ==========================================================================
186 * Used for nested transactions management.
188 private transient TransactionStatus _nestedTxStatus;
191 * Use this method to start a new transaction within an existing one.
192 * Consider the following test scenario:
194 * 1: check service.XX on valid data:
195 * - createInitialData();
196 * - service.XX(); (performs some changes on initial data)
197 * 2: check service.XX on invalid data:
198 * - deleteInitialData(); (as data were changed by previous call)
199 * - createInitialData();
200 * - adjustInitialData();
202 * To make such a test we need to provide deleteInitialData() method and call
203 * createInitialData() twice. The latter might lead to significant increasing of
204 * the test execution time.
206 * Consider an alternative approach:
208 * 1: check service.XX on valid data:
209 * - createInitialData();
210 * - startNestedTransaction();
212 * - rollbackNestedTransaction();
213 * 2: check service.XX on invalid data:
214 * - startNestedTransaction();
215 * - adjustInitialData();
217 * - rollbackNestedTransaction();
218 * Thus you're able to create and manage the nested transactions programmatically.
219 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#rollbackNestedTransaction()
221 protected void startNestedTransaction() {
222 DataSourceTransactionManager txManager =
223 (DataSourceTransactionManager) applicationContext.getBean("txManager");
225 DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
226 txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
228 _nestedTxStatus = txManager.getTransaction(txDefinition);
232 * Rollbacks the nested transaction.
233 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#startNestedTransaction()
235 protected void rollbackNestedTransaction() {
236 DataSourceTransactionManager txManager =
237 (DataSourceTransactionManager) applicationContext.getBean("txManager");
238 txManager.rollback(_nestedTxStatus);
243 * Rollbacks the nested transaction and start a new one.
244 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#startNestedTransaction()
245 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#rollbackNestedTransaction()
247 protected void rollbackAndRestartNestedTransaction() {
248 rollbackNestedTransaction();
249 startNestedTransaction();