Let’s say you’re using JUnit 4 and the Spring Testing classes (the 2.5+ versions) for your unit tests. You can specify parameters as shown in the TransactionConfiguration annotation as shown in this example. But you can also get away with leaving them out in a nod to the uberhip Convention Over Configuration gods as shown in ContextConfigurations
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class UserServiceTest extends
AbstractTransactionalJUnit4SpringContextTests {
So here the context will be loaded by classname-context.xml (e.g. UserServiceTest-context.xml) in the same package as the test class. Cool! You can save your precious digits from typing a few characters.
Let’s say you have unit tests for the persistence layer too. So you have another config file named UserDAOTest-context.xml. And so on for all your other domain classes. Lots of config files that change only a little.
Maybe one has
<aop:advisor pointcut="execution(* *..Service+.*(..))" advice-ref="txAdvice" />
and another has
<aop:advisor pointcut="execution(* *..DAO+.*(..))" advice-ref="txAdvice" />
You’re also all wet. There is nothing DRY about this. You are repeating many things with the possibility of missing one. Case in point:
I decided to try to define the datasource like this:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="org.hsqldb.jdbcDriver" p:url="jdbc:hsqldb:hsql://localhost:9001/testdb" p:username="sa" p:password="" />
instead of like this:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="org.hsqldb.jdbcDriver" p:url="jdbc:hsqldb:hsql://localhost:9001/testdb" p:username="sa" p:password="" />
Small trivial thing right? Except that I missed changing it in one of the config files. Well, what happens to the transaction rollback? Since I’m using AbstractTransactionalJUnit4SpringContextTests I want the junk I shoved into the DB in the @Before method (within the transaction) to be rolled back after the test method. Nope. Ain’t gonna happen. Do a check in @BeforeTransaction and verify in @AfterTransaction and you’ll see. But first you’ll waste a few hours tracking it down thinking the real problem is in one of those Spring XML/Annotation hell holes.
But what would happen if you decided to be unhip and say screw CoC in this case (avoiding a CoC up)?
Something like this:
@ContextConfiguration(locations = { "classpath:com/rockhoppertech/example/test-context.xml" })
OMG you had to type more. And that’s so declasse!
But then you wouldn’t have problems like I just described and you wouldn’t be repeating yourself all over the place like rainman.
















Development notes by Gene De Lisa on topics relating to
Java and various open source projects such as
the Spring Framework, Hibernate and others.
1 person has left a comment
[…] Read more: Spring Test Framework CoC suggestion […]