Spring Test Framework CoC suggestion
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
1 2 3 4 5 6 |
@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
1 2 |
<aop:advisor pointcut="execution(* *..Service+.*(..))" advice-ref="txAdvice" /> |
and another has
1 2 |
<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:
1 2 3 4 |
<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:
1 2 3 4 |
<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:
1 |
@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.
One Reply to “Spring Test Framework CoC suggestion”