views:

1404

answers:

2

What does your Spring configuration for a datasource with embedded h2 database that you use for integration (JUnit-)tests look like? My first try with a SingleConnectionDataSource basically worked, but failed on more complicated tests involving suspended transactions. You might start h2 in tcp based server mode as well, but this is probably not the fastest communication mode for a temporary embedded database in memory. What are the possibilities and their advantages / disadvantages? And how do you create the tables / populate the database?

Update: Let's specify some concrete requirements that are important for such tests.

  • The database should be temporary and in memory
  • The connection should probably not use tcp to be fast
  • It would be nice if I could use a database tool to inspect the content of the database during debugging
  • We have to define a datasource since we can't use the application servers datasource in Unittests
A: 

I think it's best to use your production DataSource implementation (only with different connection-string) for the unit-tests.

Anyway "failed on more complicated tests" doesn't give enough information for a more detailed answer.

(Self-ad : check this)

Bozho
The production database for unit-tests? If you really use e.g. an oracle database for automated tests during e.g. a maven build you can easily run into trouble. That's quite slow, depends on the data that is there and nobody else should do a build at the same time. 8-) I much prefer h2 in oracle mode.BTW: this question is rather general about the available possibilities, less about my specific problem.
hstoerr
no, the production DataSource implementation. With difference only in connection string
Bozho
Ah, OK, but that would be a datasource in an application server. So this is not possible.
hstoerr
which one is the DataSource implementation that you are using in production?
Bozho
+1  A: 

I currently include in a test-only springconfig-file as a datasource:

<bean id="database.dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
    <constructor-arg>
        <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
            <property name="driverClass" value="org.h2.Driver" />
            <property name="url"
                value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=2" />
        </bean>
    </constructor-arg>
</bean>

<!-- provides a H2 console to look into the db if necessary -->
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server" 
    factory-method="createWebServer" depends-on="database.dataSource" 
    init-method="start" lazy-init="false">
    <constructor-arg value="-web,-webPort,11111" />
</bean>

Creating / dropping the tables can be done by using executeSqlScript when overriding AbstractAnnotationAwareTransactionalTests.onSetUpBeforeTransaction, or with SimpleJdbcTestUtils.executeSqlScript in an appropriate place.

Compare also this posting.

hstoerr
"I did not find a replacement for executeSqlScript with JUnit4 tests" try extending org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests
matt b