Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to run MySQL in-memory for JUnit test cases?

Tags:

java

junit

mysql

I'm just trying to add test cases for services accessing a MySQL DB, and I would like to recreate the whole schema (and for some scenarios also just use a MySQL dump file with the data needed for each test case). I was looking around and found some guys using SQLite / H2 and others to do this, but I'm just wandering if there is any way to run MySQL in-memory so I don't need to worry about anything specific to the the MySQL dialect I might be using on our services.

like image 984
rbajales Avatar asked Jul 18 '11 14:07

rbajales


People also ask

Is mysql in memory?

It does not qualify it as in in-memory database. There are other systems that also offer in-memory options; like SQLite.

Can unit tests use databases?

It is meant to make sure that definable modules of code work as expected. To test an application it is not enough to use unit tests. You must also perform functional testing and regression testing. Database access falls outside the scope of unit testing, so you would not write unit tests that include database access.

Where should JUnit tests be stored?

They are kept in a separate directory tree to allow excluding them from the deployed result (in particular to ensure that test code didn't accidentally get into production code). What matters most, however, is what works for your situation.


2 Answers

The easiest way for using an in memory database that is fully compatible to MySQL and can be used within JUnit test cases is imho MariaDB4j. you just need a Gradle (/Maven) dependency (http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22mariaDB4j%22) and a few lines of code to start:

DB database = DB.newEmbeddedDB(3306); database.start(); Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/test", "root", ""); 

a startup script can be included via

database.source("path/to/resource.sql"); 

More information on GitHub readme: https://github.com/vorburger/MariaDB4j

EDIT: I have a add some hints to this answer: The MariaDB4j seems to add files in the systems temporary folder. So it will work in an embedded way which means there is no need to install anything and you can just use the dependency via your desired build tool. But it's not a true in-memory-only solution and therefore we cannot speak of unit tests anymore because unit tests mustn't rely on files or databases

like image 126
Andreas M. Oberheim Avatar answered Oct 10 '22 03:10

Andreas M. Oberheim


We use MySQL and flyway to handle the migration.

For unit testing and simple integration tests, we use the H2 in-memory database with the MODE=MySQL param. Mode=MySQL enables the H2 DB to handle most of the MySQL dialect.

Our test datasource in the Spring config is set up like this:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >     <property name="driverClassName" value="org.h2.Driver"/>     <property name="url" value="jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" /> </bean> 

(If you don't know Spring - the XML translates into calling new BasicDataSource and then call setDriverClassName and setUrl on the instance created)

Then we use Flyway on the datasource to create the schema and read in like we would against a regular MySQL DB:

<bean id="flyway" class="com.googlecode.flyway.core.Flyway" init-method="migrate">     <property name="dataSource" ref="dataSource" />     <property name="cleanOnValidationError" value="false" />     <property name="initOnMigrate" value="true" />     <property name="sqlMigrationSuffix" value=".ddl" /> </bean> 

You could also just use the dataSource bean in a jdbcTemplate and run some SQL scripts that way or run a number of MySQL scripts using the <jdbc:initialize-database...> tag.

like image 37
joensson Avatar answered Oct 10 '22 03:10

joensson