Wednesday, 15 January 2014

How do you reset Spring JUnit application context after a test class dirties it? -



How do you reset Spring JUnit application context after a test class dirties it? -

i'm using spring 3.1.1.release, junit 4.8.1 , hsql 2.7.7 in-memory database. have 1 test class annotated as

@runwith(springjunit4classrunner.class) @contextconfiguration({ "classpath:test-trainingsessionservicecontext.xml" }) @dirtiescontext(classmode = classmode.after_each_test_method) public class trainingsessionservicetest {

the problem is, when run "mvn clean test", seems test classes run after above class fail because in-memory database destroyed , not re-created. errors like

org.hibernate.exception.sqlgrammarexception: user lacks privilege or object not found: cb_organization" type="javax.persistence.persistenceexception">javax.persistence.persistenceexception: org.hibernate.exception.sqlgrammarexception: user lacks privilege or object not found: cb_organization @ org.hibernate.ejb.abstractentitymanagerimpl.convert(abstractentitymanagerimpl.java:1360) @ org.hibernate.ejb.abstractentitymanagerimpl.find(abstractentitymanagerimpl.java:817) @ org.hibernate.ejb.abstractentitymanagerimpl.find(abstractentitymanagerimpl.java:771) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) @ java.lang.reflect.method.invoke(method.java:597) @ org.springframework.orm.jpa.sharedentitymanagercreator$sharedentitymanagerinvocationhandler.invoke(sharedentitymanagercreator.java:240) @ $proxy46.find(unknown source) @ org.mainco.subco.organization.repo.organizationdaoimpl.findbyid(organizationdaoimpl.java:77) @ org.mainco.subco.pd.repo.linkdaotest.createdummylink(linkdaotest.java:686) @ org.mainco.subco.pd.repo.linkdaotest.testsavelink(linkdaotest.java:67) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) @ java.lang.reflect.method.invoke(method.java:597) @ org.junit.runners.model.frameworkmethod$1.runreflectivecall(frameworkmethod.java:44) @ org.junit.internal.runners.model.reflectivecallable.run(reflectivecallable.java:15)

here how setup test class (run after above class) gives exceptions …

@runwith(springjunit4classrunner.class) @contextconfiguration({ "classpath:test-context.xml" }) public class linkdaotest extends abstracttransactionaljunit4springcontexttests {

is there way can restore application context original state before each test class run? don't want create "trainingsessionservicetest" class extend abstracttransactionaljunit4springcontexttests. here relevant part of application context:

<bean id="datasource" class="org.springframework.jdbc.datasource.drivermanagerdatasource"> <property name="driverclassname" value="org.hsqldb.jdbcdriver"/> <property name="url" value="jdbc:hsqldb:mem:pd" /> <property name="username" value="sa" /> <property name="password" value="" /> </bean> <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localcontainerentitymanagerfactorybean"> <property name="jpavendoradapter"> <bean class="org.springframework.orm.jpa.vendor.hibernatejpavendoradapter"/> </property> <property name="persistencexmllocation" value="classpath:meta-inf/test-persistence.xml"/> <property name="persistenceunitname" value="testingdatabase"/> <property name="datasource" ref="datasource"/> </bean> <bean id="sharedentitymanager" class="org.springframework.orm.jpa.support.sharedentitymanagerbean"> <property name="entitymanagerfactory" ref="entitymanagerfactory"/> </bean> <bean id="transactionmanager" class="org.springframework.orm.jpa.jpatransactionmanager"> <property name="entitymanagerfactory" ref="entitymanagerfactory"/> </bean> <tx:annotation-driven /> <jdbc:embedded-database id="embedded" type="hsql"/> <jdbc:initialize-database data-source="datasource"> <jdbc:script location="classpath:db-test-data.sql"/> </jdbc:initialize-database>

use @dirtiescontext forcefulness reset. illustration have:

@contextconfiguration(classes={blahtestconfig.class}) @dirtiescontext(classmode = classmode.after_each_test_method) public class sometest { @autowired xxxx xx; @autowired yyyy yy; @before public void setup() { mockitoannotations.initmocks(this); when(yyyy.newyy()).thenreturn(zz); } @test public void testsometest() { xx.changesomething("stringtest"); xx.dosomething(); check_for_effects(); } @test public void testsomeothertest() { xx.changesomething("someotherstring"); xx.dosomething(); check_for_effects(); }

from spring docs

dirtiescontext

indicates underlying spring applicationcontext has been dirtied (modified)as follows during execution of test , should closed, regardless of whether test passed:

after current test class, when declared on class class mode set after_class, default class mode.

after each test method in current test class, when declared on class class mode set after_each_test_method.

after current test, when declared on method.

use annotation if test has modified context (for example, replacing bean definition). subsequent tests supplied new context. [note] limitations of @dirtiescontext junit 3.8

> in junit 3.8 environment @dirtiescontext supported on methods , not @ class level.

you can utilize @dirtiescontext class-level , method-level annotation within same class. in such scenarios, applicationcontext marked dirty after such annotated method after entire class. if classmode set after_each_test_method, context marked dirty after each test method in class.

@dirtiescontext public class contextdirtyingtests { // tests result in spring container beingness dirtied } @dirtiescontext(classmode = classmode.after_each_test_method) public class contextdirtyingtests { // tests result in spring container beingness dirtied } @dirtiescontext @test public void testprocesswhichdirtiesappctx() { // logic results in spring container beingness dirtied }

when application context marked dirty, removed testing framework's cache , closed; underlying spring container rebuilt subsequent test requires context same set of resource locations.

spring junit hsqldb applicationcontext

No comments:

Post a Comment