从单元测试中启动和停止hsqldb

时间:2010-06-10 20:07:00

标签: java unit-testing junit hsqldb

我正在尝试在内存模式下使用hsqldb创建集成测试。目前,我必须在运行单元测试之前从命令行启动hsqldb服务器。我希望能够从我的集成测试中控制hsqldb服务器。我似乎无法通过代码解决所有问题。

更新

这似乎与在类路径中包含hibernate.cfg.xml文件一起工作:

org.hsqldb.Server.main(new String[]{});

并在我的hibernate.cfg.xml文件中:

<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:mem:ww</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="hbm2ddl.auto">update</property>

更新 看来,使用jUnit和内置测试运行器从Eclipse中运行单元测试时,这只是一个问题。如果我跑

 mvn test

它们被正确执行,没有例外。就依赖性而言,我是否遗漏了一些东西?我使用

生成了eclipse项目
mvn eclipse:eclipse

我的pom是:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<groupId>com.myproject</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>myproject</name>

<dependencies>
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.1.2</version>
    </dependency>
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.3.2.GA</version>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc14</artifactId>
        <version>10.1.0.4.0</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.0</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.6.0</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.8.0.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.4.0.GA</version>
    </dependency>

    <!-- Test Dependencies -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.easymock</groupId>
        <artifactId>easymock</artifactId>
        <version>3.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>1.8.0.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-servlet-tester</artifactId>
        <version>6.1.24</version>
        <scope>test</scope>
    </dependency>


    <!-- Provided -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>servlet-api</artifactId>
        <version>6.0.26</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>jsp-api</artifactId>
        <version>6.0.26</version>
    </dependency>

</dependencies>

<build>
    <finalName>ww_main</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

更新 好吧,不知道这里究竟出了什么问题,但我似乎已经修好了。我删除了HSQLDB创建的所有文件,以及我的Maven目标文件夹中的所有创建文件,使用maven做了一个干净的,重新创建的eclipse .project并在eclipse中刷新了项目。我想我可能已经从以前的配置中遗留了一些东西而已经把它扔掉了。

感谢大家的帮助!

6 个答案:

答案 0 :(得分:6)

我使用以下配置(直接受Hibernate tutorial启发)没有任何问题:

<hibernate-configuration>
  <session-factory>

    <!-- Database connection settings -->
    <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
    <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:foobar"/>
    <property name="hibernate.connection.username" value="sa"/>
    <property name="hibernate.connection.password" value=""/>

    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>

    <!-- SQL dialect -->
    <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache  -->
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>

    <!-- Drop and re-create the database schema on startup -->
    <property name="hibernate.hbm2ddl.auto" value="update"/>

    <mapping resource="..."/>

  </session-factory>
</hibernate-configuration>

使用内存中的HSQLDB时,无需显式启动任何内容。只需使用mem:协议,内存数据库将从JDBC开始。

另见

答案 1 :(得分:2)

尝试将此附加到jdbc url:

;ifexists=true;shutdown=true;

答案 2 :(得分:2)

在关机方法中,只需执行

Statement st = conn.createStatement();
st.execute("SHUTDOWN");
conn.close();

答案 3 :(得分:0)

通过Runtime.getRuntime().exec("shell command here")启动服务器怎么样?对于所有测试,您只需要执行一次,因此不会增加太大的延迟。

<强>更新
好吧,看起来你自己解决了这个问题:)

更新2
要在单元测试之前(或之后)执行一次代码,您可以

static class TestWrapper extends TestSetup {
    TestWrapper(TestSuite suite) {
        super(suite);
    }

    protected void setUp() throws Exception {
        // start db
    }

    protected void tearDown() throws Exception {
        // kill db
    }
}

然后,只需将测试集包装在其中:new TestWrapper(suite)

答案 4 :(得分:0)

检查我的hsqldb maven插件: https://github.com/avianey/hsqldb-maven-plugin

您可以像测试中的jetty-maven-plugin或tomee-maven-plugin一样启动/停止它:

<plugin>

    <!-- current version -->
    <groupId>fr.avianey.mojo</groupId>
    <artifactId>hsqldb-maven-plugin</artifactId>
    <version>1.0.0</version>

    <!-- 
        default value for in memory jdbc:hsqldb:hsql://localhost/xdb
        override only values you want to change
    -->
    <configuration>
        <driver>org.hsqldb.jdbcDriver</driver>
        <path>mem:test</path>
        <address>localhost</address>
        <name>xdb</name>
        <username>sa</username>
        <password></password>
        <validationQuery>SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS</validationQuery>
    </configuration>

    <!-- call start and stop -->
    <executions>
        <execution>
            <id>start-hsqldb</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start</goal>
            </goals>
        </execution>
        <execution>
            <id>stop-hsqldb</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>

</plugin>

答案 5 :(得分:0)

也许这可能有助于在单元测试中以服务器模式启动HSQL,但是在同一个JVM中。 示例代码运行org.hsqldb.server.WebServer(即端口80),但您可以使用org.hsqldb.server.Server。您可以在上面调用setPort来覆盖默认端口。

https://stackoverflow.com/a/37784679/15789