spring-mvc-test auto rollback transactions configured with AOP xml on Service layer -
i have next spring mvc app stack:
controller -> service -> dao (repository) -> entity -> mysql innodb
transactions configured start service layer using aop xml config, , app works perfectly:
<aop:config> <aop:advisor id="managertx" advice-ref="txadvice" pointcut="execution(* *..service.*service.*(..))" order="1"/> </aop:config> <aop:aspectj-autoproxy proxy-target-class="true"/> <tx:advice id="txadvice"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> now, writing spring mvc tests using spring-mvc-test framework, unitdb etc. test class has next config:
@runwith(springjunit4classrunner.class) @contextconfiguration( loader=webcontextloader.class, locations={ "classpath:spring/testcontext.xml", "classpath:spring/testdispatcher-servlet.xml", "classpath:spring/security.xml" }) @testexecutionlisteners({ dependencyinjectiontestexecutionlistener.class, dirtiescontexttestexecutionlistener.class, transactionaltestexecutionlistener.class, dbunittestexecutionlistener.class }) @transactionconfiguration(transactionmanager="transactionmanager", defaultrollback=true) @transactional(propagation=propagation.required, rollbackfor={exception.class}) @databasesetup({"classpath:dbunit/initial-data.xml"}) the test looks this:
@test public void testsomecontroller() throws exception { this.mockmvc.perform(get("/some/controller")); } basically want test (use) existing spring aop config within testing environment, setup db data, run tests , rollback after tests completed.
in above configuration, tests starting own transaction in given propagation config meeting transaction @ service layer, started aop xml config , lock timeout error, because transaction started test waiting transaction started aop config @ service layer.
i writing tests , shouldn't modifying actual code, test code. task to find way rollback changes made tests given configuration.
any ideas appreciated.
edit
here problematic case:
test class starts 1 big new transaction auto-rollback tests. dbunit fills db initial data test launches controller test controller makes phone call service layer e.g. save/update entity (inserted dbunit @ origin of test class), new transaction started here @ service layer (configured aop:config) supported big transaction step #1 boom, error happens: lock wait timeout exceeded; seek restarting transactioni think info inserted dbunit still not committed because in same transaction. need find way insert initial info dbunit in separate transaction still roll @ end of test.
i did 3 things made work:
changed dbunittestexecutionlistener.class transactiondbunittestexecutionlistener.classmade test class extend abstracttransactionaljunit4springcontexttests
public class somecontrollertest extends abstracttransactionaljunit4springcontexttests
change info source org.apache.commons.dbcp.basicdatasource org.springframework.jdbc.datasource.transactionawaredatasourceproxy follows:
<bean id="datasource" class="org.springframework.jdbc.datasource.transactionawaredatasourceproxy"> <constructor-arg ref="dbcpdatasource"/> </bean> <bean id="dbcpdatasource" class="org.apache.commons.dbcp.basicdatasource" destroy-method="close"> <property name="driverclassname" value="${jdbc.driverclassname}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxactive" value="100"/> <property name="maxwait" value="1000"/> <property name="poolpreparedstatements" value="true"/> <property name="defaultautocommit" value="true"/> <property name="validationquery" value="select 1+1"/> <property name="testonborrow" value="true"/> </bean>
hope helps someone
spring-aop spring-transactions dbunit spring-mvc-test spring-test-dbunit
No comments:
Post a Comment