Spring transactional tests - prepare data in BeforeClass - spring

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.

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.

Spring Boot - Different Testing approaches

I've been working with Spring and Hibernate for about two years. Recently I have also been working on testing. Now I'm not quite sure if I understood everything correctly. Do I understand correctly that the following methods exist? **If I make wrong assumptions, please correct me!
Method 1:
Situation: The test class is annotated with #Transactional. The test data is created manually in an #BeforeEach method and stored in a repository.
Advantages: Through #Transactional annotation, all (BeforeEach, Test-Method, AfterEach) methods are executed in one transaction, which can be undone directly by rollback and therefore no emptying of the database is necessary.
Disadvantages: Since everything is carried out in one transaction and canceled directly by rollback, the data never ends up correctly in the database? Perhaps errors would occur during a commit? This means that the test does not reflect a real situation.
Method 2:
Situation: The test class has no #Transactional annotation. The test data is created and stored in an #BeforeEach method.
Advantages: Since the #Transactional annotation is missing, all calls of the service or controller are executed in a separate transaction, reflecting a real situation.
Disadvantages: Since everything is executed in separate transactions, the database must be completely emptied manually after each test (disable constraints and empty each table).
I have another question, but it's more subjective Do you like the initialization of test data using the #BeforeEach method and manual creation of objects and saving via repository or SQL scripts in #Sql annotation better? Initializing via SQL scripts feels faster in my opinion.

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

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.

How to setup SQL data once per Spec and clear it after Spec is completed?

I want to prepare SQL data once per Spec and remove it after Spec is completed. It should be done by Spring service
As I understand I can do following:
I can do it in setup: but it will lead to too many useless
inserts/rollbacks (if I've got few data-driven tests)
I can use #BeforeTransaction (check this example) - how to clear data after test is completed?
Annotate your test method with #Test and #Transactional and it will automatically roll back when the test is complete.

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