Series:
We will:
·
Use TDD to write Unit Test cases and build
service layer on top of persistence layer.
o
In last post we have generated persistence layer
POJO (Entity and DAOs using Hibernate Tools)
·
Follow the below steps to accomplish the above
goal.
1.
Include Spring jar dependencies in Maven.
2.
DBUnit jar dependencies in Maven. (show below
with my settings)
3.
Create context.xml with all Spring configuration
(shown below with my settings)
4.
Service layer Java class
a.
Create a proper package to hold the service
layer POJOS
b.
Create a Java Class
c.
Define/Create an template/empty method
d.
Fill in the body after setting up the Test class
and firing Junit to test the implementation
i. Implement
CRUD
ii. I
prefer to have my Queries/JQL/Criteria in this layer
iii. Include
any convenient methods/delegation
e.
Inject necessary classes via annotation
f.
Create necessary DTO (create in a separate
package)
5.
Test Classes
a.
Create a proper package to hold the Test Java
classes
b.
Create a Java Class
c.
Define a method
d.
Invoke the Service method
e.
Inject necessary classes
f.
Prepare necessary expected data set in xml
(DBUnit support DTD and not XSD)
g.
Create necessary xml files to validate actual
data (transacted via persistence layer) with that of expected data (prepared
via DBUnit framework)
i. Prepare
necessary DBUnit model (POJO) to create the expected data set if needed in
object structure. This is needed by some cases especially while reading the
data set.
ii. Prepare
basic implementation which could be reused for the specific functionality
(methods).
h.
Continuous run the method until the
implementation of service layer is complete.
i.
After the Service layer is complete re-run
necessary and previously written and run Junit test cases to ensure that there
is no regression.
6.
Fire the full test suite.
Step 1: Include Spring jar dependencies in Maven
Straight forward.
Step 2: Include DBUnit (DBUnit for Spring) jar dependencies in Maven
Straight forward.
Step 3: Create application context for Spring
1.
Include packages (persistence and service layer)
for auto scans
<context:component-scan base-package="com.mycos.<package name1>" />
<context:component-scan base-package="com.mycos.<package name2>" />
2.
Setup a DS
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
3.
Setup up EntityManagerFactory
a.
Use the correct persistenceUnitName used in
persistence.xml
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="dpdev"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
4.
Setup JpaVendorAdapter
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"/>
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
5.
Setup TransactionManager
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
6.
Annotate TransactionManager
<tx:annotation-driven transaction-manager="transactionManager" />
7.
Ensure that necessary namespace and schema
locations are included in the context.xml file
a.
Namespace
xmlns:tx="http://www.springframework.org/schema/tx"
b.
Schemalocation
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
Step 4: Service Layer
Follow the approach defined above.
1.
Inject @Service
2.
Inject @Transactional
3.
Inject PersisenceContext
4.
Inject the necessary DAO
5.
Start creating DTO which is map between service
VOs with that to Entities generated by HibernateTools
@Service
@Transactional
public class XXXService {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private
YYYTblHome userTblHome;
…
public xxxDTO getXxx(String
id) {
XxxDTO xxxDTO = new XxxDTO();
XxxTbl xxxTbl = this.xxxTblHome.findById(id);
…
public List<XxxDTO>
getXxx() {
Query query = entityManager.createQuery("SELECT p from
XxxTbl p");
Step 5: Test classes
1.
Inject Service that you want to test.
2.
Load setup/expected data (DBUnit)
3.
Convert xml into Objects if you want to compare
expected vs actual (DBUnit)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:/context.xml")
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
@Transactional
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DbUnitTestExecutionListener.class })
public class XxxDBUnitTest {
@Autowired
private XxxxService myService;
protected static final Log log = LogFactory.getLog(XxxDBUnitTest.class);
@Test
@DatabaseSetup(value="/dbunit/xyz.xml",type=DatabaseOperation.REFRESH)
@DatabaseTearDown(value="/dbunit/xyz.xml",type=DatabaseOperation.DELETE)
public void testXxx() throws Exception {
ClassPathResource
propFileName = new ClassPathResource("/dbunit/xyz.xml);
log.debug(propFileName.contentLength());
File
myDataFile = propFileName.getFile();
log.debug(myDataFile.getAbsoluteFile());
// Load expected
data from an XML dataset
IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(myDataFile);
ITable expectedTable = expectedDataSet.getTable(“table name from the xml”);
ITable actualTable = new LocationTableHelper(this. myService.getXxx("some data"));
assertEquals(expectedTable.getRowCount(), actualTable.getRowCount());
sample xml file:
<?xml version="1.0"
encoding="UTF-8"?>
<!DOCTYPE dataset [
<!ELEMENT xxx_tbl EMPTY>
<!ATTLIST xxx_tbl
xxx_ID
CDATA #REQUIRED
xx_xx
CDATA #REQUIRED>
<!ELEMENT dataset (xxx_tbl+)>
]>
<dataset>
<xxx_tbl xxx _ID="1" xx_xx ="xxx"/>
<xxx_tbl xxx _ID="2" xx_xx ="yyy"/>
<xxx_tbl LOCATION_ID="3" xx_xx ="zzz"/>
</dataset>
Maven dependencies:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>${dbunit.version}</version>
</dependency>
<dependency>
<groupId>com.github.springtestdbunit</groupId>
<artifactId>spring-test-dbunit</artifactId>
<version>${spring.dbunit.version}</version>
</dependency>
No comments:
Post a Comment