java 从单元测试中启动和停止 hsqldb
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/3018066/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
starting and stopping hsqldb from unit tests
提问by Casey
I'm trying to create integration tests using hsqldb in an in memory mode. At the moment, I have to start the hsqldb server from the command line before running the unit tests. I would like to be able to control the hsqldb server from my integration tests. I can't seem to get this to all work out though from code.
我正在尝试在内存模式下使用 hsqldb 创建集成测试。目前,我必须在运行单元测试之前从命令行启动 hsqldb 服务器。我希望能够从我的集成测试中控制 hsqldb 服务器。尽管从代码中我似乎无法解决所有这些问题。
Update:
更新:
This appears to work along with having a hibernate.cfg.xml file in the classpath:
这似乎与类路径中的 hibernate.cfg.xml 文件一起工作:
org.hsqldb.Server.main(new String[]{});
and in my hibernate.cfg.xml file:
在我的 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>
UpdateIt appears that this is only a problem when running the unit tests from within Eclipse using jUnit and the built in test runner. If I run
更新似乎这只是在 Eclipse 中使用 jUnit 和内置测试运行器运行单元测试时出现的问题。如果我跑
 mvn test
they are executed correctly and there is no exception. Am I missing something as far as a dependency goes? I have generated the eclipse project using
它们被正确执行,也不例外。就依赖而言,我是否遗漏了什么?我已经使用生成了 eclipse 项目
mvn eclipse:eclipse
and my pom is:
我的 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>
UpdateOk, well not sure what exactly was going wrong here, but I seemed to have fixed it. I deleted all the files that HSQLDB created, as well as all of the created files in my Maven target folder, did a clean, recreated my eclipse .project using maven and refreshed the project in eclipse. I think I may have had something left over from a previous configuration that was throwing it off.
更新好的,我不确定这里到底出了什么问题,但我似乎已经修复了它。我删除了 HSQLDB 创建的所有文件,以及在我的 Maven 目标文件夹中创建的所有文件,进行了清理,使用 maven 重新创建了我的 eclipse .project 并在 eclipse 中刷新了项目。我想我可能从之前的配置中遗留了一些东西,将它扔掉了。
Thanks for everyone's help!
感谢大家的帮助!
回答by Pascal Thivent
I use the following configuration (directly inspired by the Hibernate tutorial) without any problem:
我使用以下配置(直接受Hibernate 教程启发)没有任何问题:
<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>
When using an in-memory HSQLDB, there is no need to start anything explicitly. Just use the mem:protocol and the in-memory database will get started from JDBC. 
使用内存中的 HSQLDB 时,无需显式启动任何内容。只需使用该mem:协议,内存数据库将从 JDBC 启动。
See also
也可以看看
回答by Nathan Hughes
Try appending this to the jdbc url:
尝试将其附加到 jdbc url:
;ifexists=true;shutdown=true;
回答by Erik
In your shutdown method just do
在您的关机方法中,只需执行
Statement st = conn.createStatement();
st.execute("SHUTDOWN");
conn.close();
回答by avianey
check my hsqldb maven plugin : https://github.com/avianey/hsqldb-maven-plugin
检查我的 hsqldb maven 插件:https: //github.com/avianey/hsqldb-maven-plugin
You can just start/stop it like jetty-maven-plugin or tomee-maven-plugin for your tests :
您可以像 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>
回答by RuntimeException
Maybe this might help to start HSQL in server mode in a Unit test, but in the same JVM. Sample code runs org.hsqldb.server.WebServer (i.e. port 80) but you may use org.hsqldb.server.Server. You may call setPort on either to override default port.
也许这可能有助于在单元测试中以服务器模式启动 HSQL,但在同一个 JVM 中。示例代码运行 org.hsqldb.server.WebServer(即端口 80),但您可以使用 org.hsqldb.server.Server。您可以调用 setPort 来覆盖默认端口。
回答by Nikita Rybak
What about starting server through Runtime.getRuntime().exec("shell command here")? You have to do it only once for all tests, so it won't add too big lag.
通过什么启动服务器Runtime.getRuntime().exec("shell command here")?对于所有测试,您只需执行一次,因此不会增加太大的延迟。
Update
Ok, looks like you've solved it yourself :)
更新
好的,看起来您已经自己解决了:)
Update 2
To execute some code once before (or after) unit tests, you can 
更新 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
    }
}
Then, just wrap your test set in it: new TestWrapper(suite)
然后,只需将您的测试集包装在其中: new TestWrapper(suite)

