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.orm.hibernate3.HibernateTemplate;
23 import org.springframework.test.context.ContextConfiguration;
24 import org.springframework.test.context.transaction.TransactionConfiguration;
25 import org.springframework.transaction.TransactionDefinition;
26 import org.springframework.transaction.TransactionStatus;
27 import org.springframework.transaction.support.AbstractPlatformTransactionManager;
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")
99 final SessionFactory aSessionFactory) {
100 _hibernateTemplate = new HibernateTemplate(aSessionFactory);
104 * Method for the test data creation. It is called before the first test
108 public void initClass() {
110 // Initialize UserContext
111 // initUserContext();
113 } catch (Exception e) {
114 Assert.fail("Exception occured during the testing data creation. ", e);
120 * Insert base data before each method : matricule, department, language, reference.
123 public void insertBaseDataBeforeMethod() {
124 LOG.debug(" >>>>>>>>>>>>>>> COMMON - insertBaseDataBeforeMethod");
128 // [PRIVATE METHOD] ------------------------------
130 // [DATA PROVIDER METHOD : Insert / Select] ------------------------------
132 * Insert data for test : document.
135 // protected void insertData(final DocumentWithBLOBs document) {
136 // // Insert document
137 // _documentDAO.insert(document);
141 * Uses the current transaction to execute SQL statement in order to be able to
142 * see the current state of the database.
143 * @param statement the sql statement
145 @SuppressWarnings("deprecation")
146 protected void executeAndDisplaySqlStatement(final String statement) {
147 List<Map<String, Object>> resultSet = simpleJdbcTemplate.queryForList(statement);
148 displayResultset(resultSet);
152 * Uses the current transaction to execute SQL statement in order to be able to
153 * see the current state of the database.
154 * @param statement the sql statement
155 * @param args the sql statement parameters
157 @SuppressWarnings("deprecation")
158 protected void executeAndDisplaySqlStatement(final String statement, final Object...args) {
159 List<Map<String, Object>> resultSet = simpleJdbcTemplate.queryForList(statement, args);
160 displayResultset(resultSet);
164 * Displays resultset in log.
165 * @param resultSet the resultset to display.
167 private void displayResultset(final List<Map<String, Object>> resultSet) {
168 if(!resultSet.isEmpty()) {
169 Map<String, Object> firstElement = resultSet.get(0);
170 LOG.debug(firstElement.keySet().toString());
172 for (Map<String, Object> line : resultSet) {
173 StringBuilder logLine = new StringBuilder("[");
174 logLine.append(line.values());
176 LOG.debug(logLine.toString());
182 // ==========================================================================
183 // NESTED TRANSACTIONS MANAGEMENT
184 // ==========================================================================
187 * Used for nested transactions management.
189 private transient TransactionStatus _nestedTxStatus;
192 * Use this method to start a new transaction within an existing one.
193 * Consider the following test scenario:
195 * 1: check service.XX on valid data:
196 * - createInitialData();
197 * - service.XX(); (performs some changes on initial data)
198 * 2: check service.XX on invalid data:
199 * - deleteInitialData(); (as data were changed by previous call)
200 * - createInitialData();
201 * - adjustInitialData();
203 * To make such a test we need to provide deleteInitialData() method and call
204 * createInitialData() twice. The latter might lead to significant increasing of
205 * the test execution time.
207 * Consider an alternative approach:
209 * 1: check service.XX on valid data:
210 * - createInitialData();
211 * - startNestedTransaction();
213 * - rollbackNestedTransaction();
214 * 2: check service.XX on invalid data:
215 * - startNestedTransaction();
216 * - adjustInitialData();
218 * - rollbackNestedTransaction();
219 * Thus you're able to create and manage the nested transactions programmatically.
220 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#rollbackNestedTransaction()
222 protected void startNestedTransaction() {
223 AbstractPlatformTransactionManager txManager =
224 (AbstractPlatformTransactionManager) applicationContext.getBean("txManager");
226 DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
227 txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
229 _nestedTxStatus = txManager.getTransaction(txDefinition);
233 * Rollbacks the nested transaction.
234 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#startNestedTransaction()
236 protected void rollbackNestedTransaction() {
237 AbstractPlatformTransactionManager txManager =
238 (AbstractPlatformTransactionManager) applicationContext.getBean("txManager");
239 txManager.rollback(_nestedTxStatus);
244 * Rollbacks the nested transaction and start a new one.
245 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#startNestedTransaction()
246 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#rollbackNestedTransaction()
248 protected void rollbackAndRestartNestedTransaction() {
249 rollbackNestedTransaction();
250 startNestedTransaction();