There is not connection pool issue as long DataJpaTest is used for main purpose, to test repositories.
However, in my case business code is heavy coupled with database. DataJpaTest is very useful to test only business logic and real database.
The issue is that each test it tailored to specific business functionality. It works well up to 10 tests, but test 11 fails, because each cached test context reserves 10 connections and 10 tests exhausts 100 connections.
As a workaround, I configured each DataJpaTest to use 2 connections. But it does not look elegant. It would be more elegant to share connection pool across all tests
My test looks like it:
@DataJpaTest
@ImportTestContainters
@Import(Service1.class)
class Service1Test {
@Test void test_service_1(@Autowired Service1 service1) {
service1.performAction()
...
Comment From: snicoll
I am not sure how you want this to happen. It breaks all assumptions about the Test Context Framework context caching, plus sharing the connection pool means the underlying database and that's context pollution.
It's a bit unclear to me why it isn't a problem to test repositories. I suppose you're not crafting one test with @Import(Service1.class)
which basically means a separate context. Perhaps you should search how you can craft your tests so that you don't create so many contexts.If you want the connection pool to be shared, that's what you should be doing anyway.
Comment From: michaldo
Thank you for your answer
I am not sure how you want this to happen. It breaks all assumptions about the Test Context Framework context caching, plus sharing the connection pool means the underlying database and that's context pollution.
I do not know how sharing a connection poll may break something. I use test containers, so I have one database for all test suite. I do not see any scenario when shared connection poll is wrong and separated connection pool is correct. I can't exclude that it would break Test Context Framework assumptions, but by common sense connection pool should be reused by all tests. I had a vision that DataJpaTest can create parent context with connection pool and rest real context could be a child.
It's a bit unclear to me why it isn't a problem to test repositories.
It is not a real problem for testing repositories because DataJpaTest creates a single context with all defined repositories. It is another flavor of shared connection pool
I suppose you're not crafting one test with
@Import(Service1.class)
which basically means a separate context. Perhaps you should search how you can craft your tests so that you don't create so many contexts.If you want the connection pool to be shared, that's what you should be doing anyway.
I know practice of merging test context to reduce total number of contexts. I do not like it. It does not work when context has few configuration variants and limits mocking freedom. I prefer many small contexts tailored to business logic need rather than big ball od mud. DataJpaTest is very handy for me, because simply and relatively fast I can get context limited to business logic with database.
This discussion showed me another opportunity. Maybe if I like so much small and fast test contexts, I should mark them as Dirty and simply not cache connection pool. I check in my case it works
To sum up, I wanted to draw an attention that Spring tests does not reuse connection pool, what sounds expectable. If that brakes an assumption about Test Context Framework, too bad In the discussion I realized that caching context may be not good choice for my testing style Feel free to close this issue
Comment From: snicoll
I do not know how sharing a connection poll may break something.
If you configure your tests to run against a single database instance, that's one thing, but sharing something that is managed by the application context outside of its scope is scope pollution by definition. Why would we create a parent for all @DataJpaTest
-annoted tests specifically? With your setup, we could extend the reasoning to pretty much anything, which doesn't sound sane to me.
It is not a real problem for testing repositories because DataJpaTest creates a single context with all defined repositories
That's the point I was trying to convey with the context caching.
I prefer many small contexts tailored to business logic need
That is fine but each of those small contexts, as you mentioned, start part of the infrastructure. Right now it's a database, but it could be something else once you start working on another layer.
This discussion showed me another opportunity. Maybe if I like so much small and fast test contexts, I should mark them as Dirty and simply not cache connection pool.
Maybe you shouldn't be using contexts at all if you like them so tiny? Something obvious I haven't mentioned previously is that you should configure the connection pool in your tests to not reserve 10 connections.
All in all, we can't really create a parent context behind the user's back so I am going to close this but feel free to give those suggestions a try and report back if configuring the connection pool properly doesn't help.