JUnit Spring extension
Writing a plain JUnit extension is quite a straightforward task and it is described well in user-guide. It gets a bit more complicated when we try to inject Spring components into the integration testing context.
Let's try to clean up embedded Elasticsearch indexes before every integration test:
class ElasticsearchCleanerExtension : BeforeEachCallback {
override fun beforeEach(context: ExtensionContext) {
val contextManager = testContextManager(context)
val applicationContext = contextManager.testContext.applicationContext as GenericApplicationContext
val cleaner = applicationContext.getBean(ElasticsearchCleaner::class.java)
cleaner.cleanup()
}
private fun testContextManager(context: ExtensionContext):TestContextManager {
val namespace = Namespace.create(SpringExtension::class.java)
val store = context.getStore(namespace)
return store.getOrComputeIfAbsent(context.requiredTestClass, ::TestContextManager, TestContextManager::class.java)
}
}
which depends on the actual clean up component:
@Component
class ElasticsearchCleaner(val studentRepository: StudentRepository) {
fun cleanup() {
studentRepository.deleteAll()
.block(Duration.ofSeconds(2))
}
}
Each test must be annotated:
@SpringBootTest
@ExtendWith(ElasticsearchCleanerExtension::class)
class StudentPersistenceTest {
....
}
Now, the student index will be cleaned up before each test in the StudentPersistenceTest
class.