#SpringBootTest seems to ignore #OrderBy annotation on Entity - spring

I wanted to check how #OrderBy works in a Unit Test and it would still always have the entities in the order they were inserted in.
The annotation works when using the application "normally", when adding and retrieving the Entities via Web Requests. So I suspect I need to somehow close the transaction in my test first to get closer to the actual behaviour at runtime. But playing around with transactions in my tests also did not get me further.
I prepared this demo on ideas I tried so far: https://github.com/StefanLobbenmeier/spring-jpatest-kotlin-orderby/blob/d44543683c6b743525aef9a97d1f6d2341eb5b2c/src/test/kotlin/com/example/springjpatestkotlinorderby/SpringJpatestKotlinOrderbyApplicationTests.kt
to reproduce
git clone https://github.com/StefanLobbenmeier/spring-jpatest-kotlin-orderby.git
cd spring-jpatest-kotlin-orderby
./gradlew test

Related

How does Spring Boot Test keep the context across multiple test suites?

I was reading through the guide for using Spring Boot Test and there was a paragraph that got me confused.
“As our profiles get richer, it's tempting to swap every now and then in our integration tests. There are convenient tools to do so, like #ActiveProfiles. However, every time we pull a test with a new profile, a new ApplicationContext gets created.”
https://www.baeldung.com/spring-tests
So it assumes that if all tests are run under the same profile, there is only one ApplicationContext created — but how is it possible? I thought that all the objects are recreated for each test suite anyway. Am I missing something?
The official reference says that it's cached.
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/testing.html#testing-ctx-management
But how does it get loaded into the JUnit runner or Spock one across multiple test suites?
What was missing in my understanding is the fact that all the test suites are run as a part of a single program, so it's easy to cache any objects that are required by all of them, including Spring context.

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.

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.

Resources