Description
I have a use case where I need to test my repositories against several databases. For that, I use a SomeRepositoryAbstractTest
class, where I write all my tests. Then, I extend the class with children like SomeRepositoryPostgresTest
and SomeRepositoryH2Test
, with each child using a different annotation like @PostgresRepositoryTest
or @H2RepositoryTest
. This is a bit tedious and, if I ever want to add or remove a database, I will have to go through every repository test in my project.
Each annotation does things like setting up a Spring Boot context, starting Testcontainers, configuring mocks and choosing the correct Spring profiles.
An example annotation could look like this:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Testcontainers
@DataJpaTest
@EnableJpaAuditing
@TestPropertySource(properties = {"spring.jpa.hibernate.ddl-auto=validate"})
@Import({
// Common
SharedJpaRepositoryBeanConfig.class,
FakeTimeBeanConfig.class,
// Specific
SomeJpaRepositoryBeanConfig.class
})
@MockitoBean(types = DomainEventPublisher.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("postgres")
@ContextConfiguration(initializers = {PostgresContainerInitializer.class}) // Initializes Testcontainer for Spring Boot
public @interface PostgresRepositoryTest {
}
I would like to be able to do something like:
@MultiAnnotationTest({PostgresRepositoryTest.class, H2RepositoryTest.class})
class SomeRepositoryAbstractTest {
// My tests here
}
And have Junit run the test class several times, each time applying another annotation. It would be even better if I could wrap that annotation in another annotation (e.g. a custom @MultiDbRepositoryTest
), for reusability.
I have tried achieving this with the current Junit API, but it seems there is no way to add the annotation (e.g. using ByteBuddy) before annotation processing kicks in.
Deliverables
- A mechanism to run the same test class multiple times, each time with different annotations applied
- Making the mechanism work with complex tests, such as those using
@ParameterizedTest