43

使用嵌入式 h2 数据源和可选的 JUnit进行集成测试的 Spring 配置是什么样的?

我对SingleConnectionDataSource的第一次尝试基本上奏效了,但在需要同时多个连接或暂停事务的更复杂的测试中失败了。我认为基于 tcp 的服务器模式下的h2可能也可以工作,但这可能不是内存中临时嵌入式数据库的最快通信模式。

有哪些可能性及其优点/缺点?另外,您如何创建表/填充数据库?


更新:让我们指定一些对此类测试很重要的具体要求。

  • 数据库应该是临时的并且在内存中
  • 出于速度要求,连接可能不应该使用 tcp
  • 如果我可以在调试过程中使用数据库工具来检查数据库的内容,那就太好了
  • 我们必须定义一个数据源,因为我们不能在单元测试中使用应用服务器数据源
4

4 回答 4

51

保留我不知道是否有任何工具可以检查数据库,我认为一个简单的解决方案是使用支持 HSQL、H2 和 Derby的 Spring 嵌入式数据库( 3.1.x 文档当前文档) .

使用 H2,您的 xml 配置将如下所示:

<jdbc:embedded-database id="dataSource" type="H2">
    <jdbc:script location="classpath:db-schema.sql"/>
    <jdbc:script location="classpath:db-test-data.sql"/>
</jdbc:embedded-database>

如果您更喜欢基于 Java 的配置,您可以DataSource像这样实例化(注意EmbeddedDataBaseextends DataSource):

@Bean(destroyMethod = "shutdown")
public EmbeddedDatabase dataSource() {
    return new EmbeddedDatabaseBuilder().
            setType(EmbeddedDatabaseType.H2).
            addScript("db-schema.sql").
            addScript("db-test-data.sql").
            build();
}

数据库表由db-schema.sql脚本创建,并使用db-test-data.sql脚本中的测试数据填充。

不要忘记将 H2 数据库驱动程序添加到您的类路径中。

于 2012-02-07T06:13:09.407 回答
19

我目前包含在仅测试的 springconfig 文件中作为数据源:

<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>

创建/删除表可以通过在覆盖AbstractAnnotationAwareTransactionalTests.onSetUpBeforeTransaction时使用 executeSqlScript或在适当位置使用SimpleJdbcTestUtils.executeSqlScript来完成。

比较这个帖子

于 2010-01-07T10:22:53.330 回答
10

H2 捆绑了一个内置的连接池实现。以下 XML 提供了一个将其用作数据源 bean 的示例,无需引入对 DBCP 或 C3P0 的额外依赖项:

<bean id="dataSource" class="org.h2.jdbcx.JdbcConnectionPool" destroy-method="dispose">
    <constructor-arg>
        <bean class="org.h2.jdbcx.JdbcDataSource">
            <property name="URL" value="jdbc:h2:dbname"/>
            <property name="user" value="user"/>
            <property name="password" value="password"/>
         </bean>
    </constructor-arg>
</bean> 

当 Spring 应用程序上下文关闭时,将通过调用 dispose 方法关闭数据库。

于 2012-10-19T20:09:51.760 回答
0

我认为最好使用您的生产数据源实现(仅使用不同的连接字符串)进行单元测试。

无论如何,“在更复杂的测试中失败”并没有提供足够的信息来提供更详细的答案。

(自我广告:检查这个

于 2010-01-06T10:50:11.480 回答