dbunit how to sync real database with test database - dbunit

I have an application pointing to a mysql database.
I have been trying to use DBUnit to set up my tests environments, which works fine.
The problem is that when configuring DBUnit I pointed it to the SAME mysql database. So when DBUnit is executed, it takes the specified dataset.xml and overrides the information from my original database. which makes sense because there is where I am pointing it to.
The question is, am I supposed to create a new database only for tests so my DBUnit can point to it? If so, how would I manage the structure synchronization between my original database and the one for tests?
Thanks in advance.

am I supposed to create a new database only for tests so my DBUnit can point to it?
It is a better approach to do so as it eliminates multiple problems.
how would I manage the structure synchronization between my original database and the one for tests?
You don't mention tech in your persistence stack, such as Hibernate, Spring/Spring Boot/Spring Data/Flyway/LiquiBase/etc. to suggest more of how to implement this. In general, run DDL in the schema at tests run startup (either from managed DDL from something like Flyway or auto-generation from Hibernate).
Additionally, my preferred and typical testing approach is with:
An in-memory/embedded database for its speed, such as Apache Derby, automatically started just before launching tests.
Create tables in schema using Hibernate DDL gen from annotated entities.
No existing rows in any tables; happens automatically with an embedded database and a clean build when storing any of its files in a subdirectory of the build output dir.
dbUnit configured with DatabaseOperation.CLEAN_INSERT [0].
Minimal dbUnit data for each test.

Related

Programmatically recreate H2 database schema in SpringBoot application (not while unit testing)?

I have a SpringBoot application with in memory H2 database and Spring Data JPA.
I need to configure a #Scheduled job that drops and recreates the schema and loads it with fresh data from a file.
How can I programmatically recreate the schema in my application?
You can use database version control tool like eg Liquibase to create and maintain database schema definition as well as initial data. Than, you will be able to easily invoke database migration including drop of whole schema during applicaiton runtime. IT has some integration with Spring Boot already.
Keep in mind, that you will have to lock database access in order to execute migration - DDL is not transactional, so database will be of no use anyway during the migration process and you app can yeld many errors during that time.
If locking is not an option - you should be able to create another instance or at least separate schema in running instance, run migration against it and if everything is done, "switch" peristence context to use brand new schema (and probably remove the old one)

Populate database using spring / hibernate / flyway / postgresql

I'm trying to populate my database with around 150 different values (one for each row).
So far, I've found two different ways to implement the inserts, but none of them seems to be the best way to do it.
Flyway + Postgres: One of them is to create a migration file and make use of the COPY command from postgres but to do so, I need to give superuser permissions to the user and that doesn't seem to be a good choice.
Spring boot: place a data.sql file in the classpath with a lot of inserts. If I'm not wrong I would have to write 150 insert into... statements.
In previous projects, I have used liquibase and it has a loadData command which is very convenient to do what is says it does. You just give the file, table name and that's it. You end up with your csv file values in your table rows.
Is there an alike way to do that in flyway? What is the best way to populate the database?
Actually there is a way, you can find more info on the official documentation's page
You need to add some spring boot properties too:
spring.flyway.enabled=true
spring.flyway.locations=classpath:/db/migration
spring.flyway.schemas=public
Properties details here
In my case, a use Repetables scripts by my needs but take care with the prefixes
Flyway is a direct competitor of liquidbase, so if you need to track the status of migrations, manage distributed migration (many instances of the same service start simultaneously, and only one instance should actually execute a migration), check upon startup which migration should be applied and execute only relevant migrations, and all other benefits that you have previously expected from "migration management system", then you should use Flyway rather than managing SQLs directly.
Spring boot has integrations with both Flyway and Liquidbase, so you can place your migrations in the "resources" folder, define a couple of properties and spring boot will run Flyway automatically.
For example, here you can find a tutorial of Flyway integration with spring boot.
Since flyway's migrations are SQL files- you can place there whatever you want (even plSQL I believe), it will even manage transaction per migration guaranteeing that the migration "atomicity" (all or nothing, no partial migration).
So the straightforward approach would be creating a SQL file file with 150 inserts and running it via flyway in spring or even via maven depending on your actual setup.
If you want more fine-grained control and the SQL is not flexible enough, its possible to implement Migration in Java Code. See Official Flyway Documentation

Integration testing of EJBs

I have a set of EJBs, which persist and retrieve data from a Sybase database through a set of DAO classes.
The DAO classes are POJOs, which execute directly sql procedures(prepared statement) over JDBC datasource.
What would be the appropriate framework to prepare an integration testing suite for these EJBs ,using some meaningful simulated data in the database?
Does spring/junit provide some help?
Any advice is appreciated.
I think unit testing is enough depending on what you're trying to validate.
If you need to test only the EJB I would go with a mocked version of your DAO that work in-memory (a DAO with a HashMap to save and retrieve data for example) so you can focus your tests on the input and output of your EJB methods. This way you can also populate your test data programmatically.
If you also need to test the Sybase statements generated by your DAO I think you could separate the methods that actually execute the statements from those that generate the SQL, this way you could validate the SQL generated without needing a connection to the database.
If you really need to validate your tests against the database engine you could try to configure a Profile for your Integration tests with a valid database connection and bind this connection to your DAO bean. You can even populate this database with some testing data via script.

How can I create an in-memory test database when the table mappings are using other databases?

I'm trying to create some tests for an application that uses Spring and JPA (with Hibernate).
I want to use an in-memory database so that I can check if everything is working without having to depend on the main development server (which is an old Sybase installation), and also will allow me to isolate better the tests functionality.
Problem is, there are a lot of tables that are mapped using #Table("dbname..dbo.someviewname") to access views from other databases.
So, I was trying to use HSQLDB with DBunit, but HSQLDB understandbly does not allow to create tables with dots in their names.
How can I do tests against that?
Should I give up of the in-memory thing and do tests using the main Sybase development server (risking to ruin it for the other devs :P)?
From dbname.dbo.someviewname HSQLDB likely extracts dbname as catalog, dbo as schema and somewiewname as table name.
HSQLDB do allow creating tables which have dot in their names. That can be done by treating table name as delimited identifier:
#Table(name="\"dbname.dbo.someviewname\"")
But you do not want to use that, because then how names are treated is changed also for Sybase. If you can have separate orm.xml for tests, then you can add following to orm.xml:
<persistence-unit-defaults>
<delimited-identifiers/>
</persistence-unit-defaults>
It causes all database object names to be treated as delimited identifiers. Depending about your mappings and queries it can eventually work, but most likely you will face some problems. Likely best approach is not to have schema names in mappings and/or separate Sybase instance for tests.

HSQL Unit Test -- How to Create Multiple In-Memory Schemas?

I would like to use hsql within my DAO unit tests for a web application. The web app is written against mysql and uses three different schemas within the same mysql database. Some schemas has FK relationships with data in the other schemas. If I'm to unit test, I must be able to execute against a database that can hold multiple schemas.
I know that HSQL supports multiple schemas, but I don't know how to configure hsql to have multiple schemas set up for an in-memory database. I read that I can define multiple schemas in the server.properties file, but the file needs to be in the location of where the java class was called -- the junit.jar location? If so, that would be hard to support in my Java Maven application. How can I:
Run an in-memory hsql database to start up with three databases?
Where would I place the server.properties file in my Maven app?
Could I point hsql to use a server.properties file in a location other than where the junit jar is (that's a showstopper for me)?
Is it possible to configure multiple schemas for an in-memory database just via a tricked out jdbc url?
I wish I could untangle the schemas from each other, but that's not possible at this time.
Thanks for your help!
HSQLDB supports multiple schemas in the same database. Foreign keys can reference tables from different schemas. The following apply to the very latest HSQLDB 2.2.6 snapshot available from http://hsqldb.org
Before running your tests, execute CREATE SCHEMA schemaname for each schema.
Doesn't matter where, you can specify the absolute path on the command line arguments when running. See the HSQLD Guide and JavaDoc on server.
Yes.
No. You use the SQL statement to create the schemas.
Note you have two options for running HSQLDB, one is as a server, the other is as an embedded database. In the case of server, it must be started before the test run. In both cases, you need to connect to the database and create the schemas before your tests.
It is possible to create different db by setting db name. By default, it creates the db name as testdb, but in case we want to create multiple db, then set the name explicitly.
new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL).setName("DB_NAME")
.addScript("DDL.SQL")
.addScript("DML.SQL")
.build();
If you run the below line mutiple time, you can see the databases:
DatabaseManagerSwing.main(new String[] { "--url", "jdbc:hsqldb:mem:" + dbnaes, "--user", "sa", "--password", "" });

Resources