I have configured a custom annotation:
@Target(allowedTargets = [AnnotationTarget.TYPE, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS])
@Retention(AnnotationRetention.RUNTIME)
@ExtendWith(value = [SpringExtension::class, BuilderTestExtension::class])
@ContextConfiguration(classes = [TestConfig::class])
@SpringBootTest
annotation class BuilderTest
and also I have configured the TestConfig:
@ContextConfiguration
@ComponentScan(
basePackages = ["com.example.api.base.builder"]
)
class TestConfig
the BuilderHelper is defined as such where ResponseBuilder class is defined in com.example.api.base.builder
package:
@Service
class BuilderHelper(@Autowired var responseBuilder: ResponseBuilder)
everything works fine so far. When I try though to create another annotation for serialization tests such as:
@Target(allowedTargets = [AnnotationTarget.TYPE, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS])
@Retention(AnnotationRetention.RUNTIME)
@ExtendWith(value = [SpringExtension::class, SerializationTestExtension::class])
@ContextConfiguration(classes = [SerializationConfig::class])
@SpringBootTest
annotation class SerializationTest
Serialization config file is defined:
@ContextConfiguration
@ComponentScan(
basePackageClasses = [ObjectMapper::class]
)
class SerializationConfig
and SerializationHelper where ObjectMapper
class is an external library with package name com.fasterxml.jackson.databind
:
@Service
class SerializationHelper(@Autowired var objectMapper: ObjectMapper)
Now my error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' available: expected at least 1 bean which qualifies as autowire candidate
which I assume is because of the configuration. Somehow I want to make those 2 annotations or extensions independent. Any ideas?
I think what you are trying to do is a little bit overcomplicated.
You can make use of @TestConfiguration
annotation in order to completely isolate your testContext from applicationContext.
Reference: TestConfiguration
What I suggest that you can do is this:
Modify your @BuilderTest
annotation as such:
@Target(allowedTargets = [AnnotationTarget.TYPE, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CLASS])
@Retention(AnnotationRetention.RUNTIME)
@Import(TestConfig::class)
@ExtendWith(SpringExtension::class)
annotation class BuilderTest
as you can see the @SpringBootTest
annotation is missing so that you can isolate the context for test classes specifically. Furthermore you no longer need @ContextConfiguration
annotation.
Modify your TestConfig as such:
@TestConfiguration
class TestConfig {
@Bean
fun responseBuilder(): ResponseBuilder {
// return the instance of ResponseBuilder class here
}
}
Then in your test class you can simply do this:
@BuilderTest
class ResponseBuilderTest {
@Autowired
lateinit var responseBuilder: ResponseBuilder
@Test
fun testResponseBuilder() {
// your test logic goes here
}
}
you can follow this procedure and do the same for @SerializationTest
by creating an additional Configuration class using the @TestConfiguration
annotation and providing the instance for ObjectMapper
.