I have a web application that defines a Hibernate Integrator as part of the Java ServiceLoader specification like so:
src/main/resources/META-INF/services/org.hibernate.integrator.spi.Integrator
# Define integrators that should be instantiated by the ServiceLoader
org.emmerich.MyIntegrator
This is done according to the Hibernate guide here.
My issue is that when I try to perform unit tests, the main Integrator descriptor is still parsed and instantiated. This means that, because I'm mocking a large portion of the application in unit tests, when the integrator tries to run it encounters errors which causes my tests to fail.
I've defined the same file in the test resources:
src/test/resources/META-INF/services/org.hibernate.integrator.spi.Integrator
# Empty file to try and overwrite the main deployment description.
but instead I find that both test and main integrator files are parsed.
I expected that the test resource would overwrite the main resource, thus rendering the main resource obscolete, but that's not what happens. As both files are on the classpath (I'm running the tests through Maven with the surefire-plugin, which puts both test-classes
and classes
on the classpath). A similar thing happens with persistence.xml
.
In my unit testing environment I don't want any Integrators to be instantiated because I want to control the construction of these beans as manually as possible. Give that I'm testing units of execution, I don't want additional beans such as Integrators lying around that may affect the running of the tests. I think this is a perfectly legitimate requirement during unit testing. However, whilst the main resources are still parsed by the ServiceLoader
, this isn't possible.
The solution I've come to do is based on the persistence.xml
solution posted here:
How to configure JPA for testing in Maven
My question is whether there's a better way of excluding main resources from being processed during unit testing than forcing renaming, especially in the context of ServiceLoader
files?
To try and summarize it a bit better:
What happens when you have two files both named after the same service interface on the classpath? To me, it seems that all services within both files are instantiated. There is no overwriting, it would seem.