@Transaction and repository testing
-
21-12-2019 - |
Question
I've seen that @Transactional
is better placed at the service layer but the problem is that I'm not able to test my repositories correctly because the changes are not commited.
When testing the repository save()
method, I want to use find()
to see if the entity was correctly saved but because save()
changes are not commited to the database, find()
returns null.
The only solutions I see is to add the @Transactional
annotation:
- on the repository
save()
method - on the
testSave()
method => but IMO this is wrong because it modifies the behavior
Maybe I'm misunderstanding something, I started to learn Java two days ago.
Solution
You don't need the changes committed to the database you only need the queries issued in the same transaction. Next you shouldn't be using the same means by which you store the data to retrieve the data. Basically you should use plain jdbc to test if it was added.
public class TestClass extends AbstractTransactionalSpringJUnit4ContextTests {
private TestRepository repo;
@Test
public void testSave() {
int rowCount = countRowsInTable("your-table-name");
repo.save(yourEntity);
repo.flush();
int rowCountAfter = countRowsInTable("your-table-name");
assertTrue(rowCountAfter - rowCount == 1); // Or whatever you like to verify the row was added
}
Note: If you don't extend JpaRepository
there is no flush
method, instead you can inject the EntityManager
in the testcase and call flush
on there.
Instead of only testing the row count you could also use the jdbcTemplate
from the AbstractTransactionalJunit4SpringContextTests
to retrieve the newly added row and compare with what you expected it to be.
OTHER TIPS
That's why you would start testing by writing unit tests while writing production code. But as you started learning Java just two days ago you really should not get into transaction management right off the bat. Learn the basics and the design first.