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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 23:58:06  来源:igfitidea点击:

starting and stopping hsqldb from unit tests

javaunit-testingjunithsqldb

提问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 来覆盖默认端口。

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

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

回答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)