Spring Data Jpa. How to cleaning data from repositories befor run unit test from particular test classes? - spring

I have problem with unit tests for persistance stuff written in spring data jpa.
For particular repositories I have a unit tests to be sure that everything works correctly. Also I have a integration tests. Each tests are passed when I run it for particular test classes. But when i run a whole package of tests I got a lot of faliures because I have records inserted into DB from previous tests.
Of course in each test classes I can add #After method to clean each data but I would like to ask that it posible to clean all data from DB before run tests from particular test classes without adding #After method?
Best Regards.

Use Spring's transactional test support to ensure that database changes are rolled back after each test:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#testcontext-tx
One common issue in tests that access a real database is their effect
on the state of the persistence store. Even when you’re using a
development database, changes to the state may affect future tests.
Also, many operations — such as inserting or modifying persistent
data — cannot be performed (or verified) outside a transaction.
The TestContext framework addresses this issue. By default, the
framework will create and roll back a transaction for each test.

Related

How can I have a clean databse for every JUnit test?

Problem: When an integration test fails, it often not delete his test data (I mostly use DbUnit for that). Because of this, other tests will also fail (for example because they want to delete their test data, but it is referenced by data which shouldn't exist at this point --> test will fail).
Is there a possibility that Jenkins use for every single test or for every Java test class a fresh/clean database with the init data (I don't need a complete empty database), that my integration tests are more independent?
Use a spring.jpa.hibernate.ddl-auto=create-drop property or annotate your test class with #Transactional.

Junit test that persist in mysql

Is it possible to write junit test that persist in mysql using hibernate / jpa?
If so any example available?
I'm using spring/hibernate for my application
When you have real database connection I would not call your test unit test, but more like integration test. To be honest this kind of tests is not a good idea in most cases. It requires some maintenance (every time you have changes in db), and in most cases just tests if it is possible to connect do database (and save some simple object).
Focus on writing good tests for domain level classes. Simple database integration tests will only give you illusion of high quality application.
If you want to write an integration test that looks like a unit test, you could try Arquillian.
What Arquillian does is basically start an application container (Glassfish I think is the default), then it deploys your server-side application in the container and runs the tests against the just-deployed application.
What you write in the unit tests is really client code, so that what you are effectively running is an integration test (with a real database and all the services you would have in a real environment), just in a junit-like way.
They also have a specific tutorial for persistence testing.

Spring transactional tests - prepare data in BeforeClass

I would like to create some data in #BeforeClass and use them in my #Test method.
After all tests are finished (failed or succeeded), I would like to rollback the data.
Can this be achieved using the annotations #BeforeClass, #Transactional, without having to clean up the data explicitly?
We had a similar problem here. Our solution was to give each test class an embedded H2 database (just takes a couple of seconds to setup the first one; after that, it's not really noticeable anymore).
That allowed us to load any kind of test data into the database, no need to clean that up after all tests have run.
Each test still gets its own transaction, so after each individual test, the per-class database is rolled back to the original state.
To debug tests, we would annotate the individual test with #Transactional(rollback=false), so we could look at the database with an SQL tool.
Another test would examine all tests classes, looking for this annotation to make sure no one accidentally commits it.

Multiple Spring integration test files with different context configs prevents successul persistence

I have two separate integration test files, each with their own context configuration files (XML). When I incorporate both of them into the build cycle, I run into problems, but if I put the #Ignore annotation on one of them, everything works fine.
The specific problem I'm having is with persistence; when both integration tests are in the build cycle, one of my tests does not persist objects correctly to the database. I don't get errors, and it says it's persisting, and Hibernate outputs the log entry saying it is inserting, but when I check the database table, nothing is there. Then when I run the test by itself (#Ignore on the other test), it writes to the database table as it should.
Does it matter that I'm using some of the same variable names in the context config files? For example, both files have a transaction manager called "deviceTxManager". I figured this was OK since they are completely separate configuration files used for different tests.
Should I be somehow "purging" the context of the previous integration test before running the next test?
The culprit was in my persistence.xml file. I am using
<property name="hibernate.hbm2ddl.auto" value="create" />
which apparently is used separately by each separate integration test class. So, the second integration test was recreating the database schema, thus purging the database changes made by the preceding integration test.
I thought persistence.xml was only accessed once before all integration tests are run, but apparently I was wrong; it is accessed separately by each separate integration test class and the database is cleared and recreated for each test class.

In TDD, why OpenEJB and why Arquillian?

I'm a web developer ended up in some Java EE development (Richfaces, Seam 2, EJB 3.1, JPA). To test JPA I use hypersonic and Mockito. But I lack deeper EJB knowledge.
Some may argue that we should use OpenEJB and Arquillian, but for what?
When do I need to do container dependent tests? What are the possible test scenarios where I need OpenEJB and Arquillian?
Please enlighten me :)
There are two aspects in this case.
Unit tests. These are intended to be very fast (execute the whole test suite in seconds). They test very small chunks of your code - i.e. one method. To achieve this kind of granularity, you need to mock the whole environment using i.e. Mockito. You're not interested in:
invoking EntityManager and putting entities into the database,
testing transactions,
making asynchronous invocations,
hitting the JMS Endpoint, etc.
You mock this whole environment and just test each method separately. Unit tests are fine-grained and blazingly fast. It's because you can execute them each time you make some important changes in code. If they were more complex and time-consuming, the developer wouldn't hit the 'test' button so often as he should.
Integration tests. These are slower, as you want to test the integration between your modules. You want to test if they 'talk' to each other appropriately, i.e.:
are the transactions propagated in the way you expect it,
what happens if you invoke your business method with no transaction at all,
does the changes sent from your WebServices client, really hits your endpoint method and it adds the data to the database?
what if my JMS endpoint throw an ApplicationException - will it properly rollback all the changes?
As you see, integration tests are coarse-grained and as they're executed in the container (or basically: in production-like environment) they're much slower. These tests are normally not executed by the developer after each code change.
Of course, you can run the EJB Container in embedded mode, just as you can execute the JPA in Java SE. The point is that the artificial environment is giving you the basic services, but you'll end with tweaking it and still end with less flexibility than in the real container.
Arquillian gives you the ability to create the production environment on the container of your choice and just execute tests in this environment (using the datasources, JMS destinations, and a whole lot of other configurations you expect to see in production environment.)
Hope it helps.
I attended Devoxx this year and got a chance to answer the JBOSS dudes this question.
Some of the test scenarios (the stuff i managed to scribble down):
Configuration of the container
Container integration
Transaction boundaries
Entity callback methods
Integration tests
Selenium recordings

Resources