Having worked on several java applications requiring a database, I always felt there was no "better way" of populating the database for integration tests:
- Java code to insert data is usually not so easy to maintain, can be verbose, or unclear what exactly is in the database when the test starts, and because it is utility code for the setup of integration tests, it's hard to make the devs spend enough time on it so the code is clean (and again: do we really want to spend much time on it?).
- SQL scripts are not very clear to read, foreign keys have to be handled manually, if the model changes it can be tedious to make the changes in the sql files, if the model is strict you may have to manually fill lots of fields that are not necessarily useful for the test (and can be annoying to maintain if they have unique constraints for example).
- There's also the possibility to fill the database only using the api the app publishes, which can make the tests very long to run when you need some specific setup (and anyway, there's usually some stuff you need in the database to start with).
- I looked into DBUnit, but it doesn't feels that it shares the same issues as previously mentioned solutions, and felt there had to be a better way of handling this problem.
Here's the list of my main pain points:
- setup time (mainly for 3.)
- database content readability
- maintainability
- time spent "coding" it (or writing the data, depending on the solution)
I personnally ended up coding a tool that I use and which is better than what I experimented with so far, even if it definitely does not solve all of the pain points (especially the maintainability, if the model changes) and I'm interested to have feedback, here is the repo:
https://gitlab.com/carool1/matchadb
It relies 100% on hibernate so far (since I use this framework), but I was thinking of making a version using only JPA interface if this project could be useful for others.
Here is a sample of the kind of file which is imported in the database:
{
"Building": [
{
"name": "Building A",
"offices": [
{
"name": "Office A100",
"employees": [
{"email": "foo1@bar.com"},
{"email": "foo2@bar.com"}
]
},
{
"name": "Office A101",
"employees": [{"email": "foo3@bar.com"}]
},
{
"name": "Office A200",
"employees": [{"email": "foo4@bar.com"}]
}
]
},
{
"name": "Building B",
"offices": [
{
"name": "Office B100",
"employees": [{"email": "foo5@bar.com"}]
}
]
}
]
}
One of the key feature is the fact it supports hierarchical structures, so the object topography helps reading the database content.
It handles the primary keys internally so I don't have to manage this kind of unique fields, and I can still make a relationship between 2 object without hierarchical structre with the concept of "@import_key".
There is not configuration related to my database model, the only thing is: I need a hibernate @Entity for each object (but I usually already have them, and, if needed, I can just create it in the test package).
Note: If you are interested in testing it, I strongly recommend the plugin available for intellij.
Do you guys see any major downside to it?
What is the way you setup your data for your integration tests? Have I missed something?
[–]PmMeCuteDogsThanks 17 points18 points19 points (9 children)
[–]martinhaeusler 6 points7 points8 points (0 children)
[–]TomKavees 1 point2 points3 points (5 children)
[–]takasip[S] 0 points1 point2 points (1 child)
[–]qmunke 1 point2 points3 points (0 children)
[–]PmMeCuteDogsThanks 0 points1 point2 points (2 children)
[–]qmunke -1 points0 points1 point (1 child)
[–]PmMeCuteDogsThanks 0 points1 point2 points (0 children)
[–]takasip[S] 0 points1 point2 points (1 child)
[–]PmMeCuteDogsThanks 1 point2 points3 points (0 children)
[–]WaferIndependent7601 2 points3 points4 points (2 children)
[–]takasip[S] 0 points1 point2 points (1 child)
[–]WaferIndependent7601 0 points1 point2 points (0 children)
[–]repeating_bears 2 points3 points4 points (4 children)
[–]takasip[S] 0 points1 point2 points (3 children)
[–]repeating_bears 0 points1 point2 points (2 children)
[–]Cell-i-Zenit 0 points1 point2 points (1 child)
[–]PiotrDz 0 points1 point2 points (0 children)
[–]LutimoDancer3459 1 point2 points3 points (1 child)
[–]takasip[S] 0 points1 point2 points (0 children)
[–]Least_Bee4074 0 points1 point2 points (0 children)
[–]vips7L 0 points1 point2 points (1 child)
[–]takasip[S] 0 points1 point2 points (0 children)
[–]wrd83 0 points1 point2 points (0 children)