我可以为junit测试克隆MySQL数据库使用HSQLDB吗?

3

我正在开发一个Spring Webflow项目,我在思考是否可以在JUnit测试中使用HSQLDB而不是MySQL?

如何将我的MySQL数据库克隆到HSQLDB中?


1
你正在使用Spring和Hibernate吗?请同时告知Spring的版本。 - Manuel Quinones
是的,我正在使用Spring和Hibernate。 - techsjs2013
2个回答

4
如果您使用的是Spring 3.1或更高版本,可以使用Spring Profiles来实现这一点。当没有设置活动配置文件时,将加载默认配置文件。
<beans profile="dev">
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close"> 
        <property name="driverClass" value="org.hsqldb.jdbcDriver" />
        ...other datasource properties also create or drop db
    </bean>
</beans>
<beans profile="default">
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close"> 
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        ...other datasource properties
    </bean>
</beans>

在您的单元测试中,通过添加注释来设置活动配置文件。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:app-config.xml")
@ActiveProfiles("dev")
public class TransferServiceTest {

2
除了建议之外,需要考虑您的需求,HSQL和MySQL并不具有相同的功能,例如合并连接和其他非标准SQL功能。 因此,在我们的情况下,我们始终在嵌入式Mysql上运行测试。
嵌入式MySQL是使用mysql-connector-mxj提供的。如果您使用Maven,可以像这样获取它:
<dependency>
   <groupId>mysql</groupId>
       <artifactId>mysql-connector-mxj</artifactId>
       <version>5.0.12</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-mxj-db-files</artifactId>
        <version>5.0.12</version>
</dependency>

一旦驱动程序在您的项目路径上,您可以直接从Java启动数据库。在我们的情况下,我们有这个实用类来启动数据库:

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mysql.management.MysqldResource;
import com.mysql.management.MysqldResourceI;

public class EmbeddedMySQLDb {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    private MysqldResource mysqldResource;
    private String baseDatabaseDir = System.getProperty("java.io.tmpdir");
    private String databaseName = "test_db_" + System.nanoTime();
    private int port = 13306;
    private String username = "root";
    private String password = "password";

    /**
     * Starts the mysql database
     * @return
     */
    public void startDatabase() {
        if (logger.isDebugEnabled()) {
            logger.debug("=============== Starting Embedded MySQL using these parameters ===============");
            logger.debug("baseDatabaseDir : " + baseDatabaseDir);
            logger.debug("databaseName : " + databaseName);
            logger.debug("host : localhost (hardcoded)");
            logger.debug("port : " + port);
            logger.debug("username : " + username);
            logger.debug("password : " + password);
            logger.debug("=============================================================================");
        }

        File databaseDir = new File(new File(baseDatabaseDir), databaseName);

        mysqldResource = new MysqldResource(databaseDir);

        Map<String, String> database_options = new HashMap<String, String>();
        database_options.put(MysqldResourceI.PORT, Integer.toString(port));
        database_options.put(MysqldResourceI.INITIALIZE_USER, "true");
        database_options.put(MysqldResourceI.INITIALIZE_USER_NAME, username);
        database_options.put(MysqldResourceI.INITIALIZE_PASSWORD, password);

        mysqldResource.start("embedded-mysqld-thread-" + System.currentTimeMillis(), 
                             database_options);

        if (!mysqldResource.isRunning()) {
            throw new RuntimeException("MySQL did not start.");
        }

        logger.info("MySQL started successfully @ " + System.currentTimeMillis());


    }

    /**
     * Shutdowns the mysql database
     * @return
     */
    public void shutdownDatabase() {
        mysqldResource.shutdown();
        if (mysqldResource.isRunning() == false) {
            logger.info(">>>>>>>>>> DELETING MYSQL BASE DIR [" + mysqldResource.getBaseDir() + "] <<<<<<<<<<");
            try {
                FileUtils.forceDelete(mysqldResource.getBaseDir());
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }



    //-------------------------------------------------------------------------
    /**
     * @return the baseDatabaseDir
     */
    public final String getBaseDatabaseDir() {
        return baseDatabaseDir;
    }

    /**
     * @param baseDatabaseDir the baseDatabaseDir to set
     */
    public final void setBaseDatabaseDir(String baseDatabaseDir) {
        this.baseDatabaseDir = baseDatabaseDir;
    }

    /**
     * @return the databaseName
     */
    public final String getDatabaseName() {
        return databaseName;
    }

    /**
     * @param databaseName the databaseName to set
     */
    public final void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }

    /**
     * @return the port
     */
    public final int getPort() {
        return port;
    }

    /**
     * @param port the port to set
     */
    public final void setPort(int port) {
        this.port = port;
    }

    /**
     * @return the username
     */
    public final String getUsername() {
        return username;
    }

    /**
     * @param username the username to set
     */
    public final void setUsername(String username) {
        this.username = username;
    }

    /**
     * @return the password
     */
    public final String getPassword() {
        return password;
    }

    /**
     * @param password the password to set
     */
    public final void setPassword(String password) {
        this.password = password;
    }   
}

一旦创建了数据库,连接数据库只需要使用以下类似的DB url:

String url = "jdbc:mysql:mxj://localhost:" + port + "/" + dbName;

祝好!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接