I have an application that listens for Kafka messages using @KafkaListener
inside of a @Component
. Now I'd like to make an integration test with a Kafka test container (which spins up Kafka in the background). In my test I want to verify that the listener method was called and finished, however when I use @SpyBean
in my test I get:
No bean found for definition [SpyDefinition@7a939c9e name = '', typeToSpy = com.demo.kafka.MessageListener, reset = AFTER]
I'm using Kotling, important classes:
Class to test
@Componentclass MessageListener(private val someRepository: SomeRepository){ @KafkaListener fun listen(records: List<ConsumerRecord<String, String>>) { // do something with someRepository }}
Base test class
@ExtendWith(SpringExtension::class)@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)@TestInstance(TestInstance.Lifecycle.PER_CLASS)class KafkaContainerTests { // some functionality to spin up kafka testcontainer}
Test class
class MessageListenerTest @Autowired constructor( private val someRepository: SomeRepository) : KafkaContainerTests() { @SpyBean private lateinit var messageListenerSpy: MessageListener private var messageListenerLatch = CountDownLatch(1) @BeforeAll fun setupLatch() { logger.debug("setting up latch") doAnswer { it.callRealMethod() messageListenerLatch.count }.whenever(messageListenerSpy).listen(any()) } @Test fun testListener(){ sendKafkaMessage(someValidKafkaMessage) // assert that the listen method is being called & finished assertTrue(messageListenerLatch.await(20, TimeUnit.SECONDS)) // and assert someRepository is called }}
The reason I am confused is that when I add the MessageListener to the @Autowired
constructor of the MessageListenerTest
it does get injected successfully.
Why is the test unable to find the bean when using @SpyBean
?