Can I use HSQLDB for junit testing cloning a mySQL database

谁说胖子不能爱 提交于 2019-12-06 06:58:42

问题


I am working on a spring webflow project and I am thinking can I use HSQLDB and not my mysql for junit testing?

How can I clone my mysql database into HSQLDB


回答1:


If you are using spring 3.1 or greater you could use spring profiles to achieve this. The default profile is loaded when no active profile is set.

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

In your unit test set the active profile by adding the annotation.

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



回答2:


Beside of the suggestions, take in consideration that depending of your needs, HSQL and MySQL doesn't have the same features like merge joins and other SQL non standard features. Because of this (in our case), we always run our tests over an embedded Mysql.

The embedded MySQL is provided with the mysql-connector-mxj. If you use Maven, you can get it like this:

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

Once the driver is on the path of your project, you can just start the database from Java. In our case, we have this utility class that starts the database:

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

To connect to the DB once is created, you have just to use as the DB url something like this:

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

Regards,



来源:https://stackoverflow.com/questions/14607665/can-i-use-hsqldb-for-junit-testing-cloning-a-mysql-database

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!