'SpringBootTest with @EmbeddedKafka, @KafkaListener not invoked when using @MockBean

I'm seeing an issue when using @MockBean whereby the class under test contains a @KafkaListener annotation and isn't invoked.

I've tried the following:

  • @SpyBean
  • A TestConfiguration class with the bean containing @KafkaListener with a mock
  • Removing the base class which brings in a bunch of producer configs to publish to embedded broker

Something that did actually work was changing the dependency to var and replacing it in a @BeforeEach in the Test class

Test class:

@SpringBootTest
@ContextConfiguration(
    initializers = [ITKafkaPropertiesContextInitializer::class]
)
@EmbeddedKafka(
    controlledShutdown = true,
    ports = [9093],
    topics = [
        "embedded-test-topic-1",
        "embedded-test-topic-2"
    ],
    partitions = 1,
    brokerProperties = [
        "PLAINTEXT://localhost:9093"
    ]
)
class ConsumerITTest : AbstractKafkaTest() {

    @Autowired
    lateinit var kafkaTemplate: KafkaTemplate<String, Message>


    @Value("\${spring.kafka.event-topic}")
    lateinit var kafkaTopic: String

    @MockBean
    lateinit var delegator: MessageDelegator

    @Test
    fun `should receive message and invoke delegator`() {
        val event = JsonReader.read("src/test/resources/messages/create.json", Message::class.java)

        eventKafkaTemplate.send(
            ProducerRecord(producerRecord)
        )

        await().atMost(Duration.FIVE_SECONDS).untilAsserted {
          ...
        }

    }

}

Without the @MockBean everything works as expected, with @MockBean I can't even reach the breakpoint because the @KafkaListener function is never called.

@Component
class Consumer(
    val delegator: Delegator
) {
    private val logger = KotlinLogging.logger {}

    @KafkaListener(
        topics = ["#{'\${spring.kafka.topic}'}"],
        groupId = "#{'\${spring.kafka.consumer.group-id}'}",
        containerFactory = "eventContainerFactory"
    )
    fun onMessage(
        @Payload data: ConsumerRecord<String, Message>?,
        @Headers headers: Map<String?, ByteArray?>,
    ) {
      ... //Breakpoint here never reached when using @MockBean

Just to confirm, this all works totally fine until I use these annotations to replace with a bean in the context with a mock



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source