Простой встроенный тестовый пример Kafka с spring boot
редактировать FYI:рабочий пример gitHub
Я искал в интернете и не мог найти рабочий и простой пример встроенного теста Кафки.
Моя настройка:
- Весна загрузки
- несколько @KafkaListener с различными темами в одном классе
- встроенный Кафка для теста, который начинается нормально
- тест с Kafkatemplate, который отправляет в тему, но этот @KafkaListener методы не получают ничего даже после огромного времени сна
- не отображаются предупреждения или ошибки, только информационный спам от Кафки в логах
пожалуйста, помогите мне. Есть в основном более сконфигурированные или перегруженные примеры. Я уверен, что это можно сделать просто. Спасибо, ребята!
@Controller
public class KafkaController {
private static final Logger LOG = getLogger(KafkaController.class);
@KafkaListener(topics = "test.kafka.topic")
public void receiveDunningHead(final String payload) {
LOG.debug("Receiving event with payload [{}]", payload);
//I will do database stuff here which i could check in db for testing
}
}
частная статическая строка SENDER_TOPIC = " test.Кафка.тема";
@ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, SENDER_TOPIC);
@Test
public void testSend() throws InterruptedException, ExecutionException {
Map<String, Object> senderProps = KafkaTestUtils.producerProps(embeddedKafka);
KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps);
producer.send(new ProducerRecord<>(SENDER_TOPIC, 0, 0, "message00")).get();
producer.send(new ProducerRecord<>(SENDER_TOPIC, 0, 1, "message01")).get();
producer.send(new ProducerRecord<>(SENDER_TOPIC, 1, 0, "message10")).get();
Thread.sleep(10000);
}
2 ответов
встроенные тесты Кафки работают для меня с приведенными ниже конфигурациями,
Аннотация к тестовому классу
@EnableKafka
@SpringBootTest(classes = {KafkaController.class}) // Specify @KafkaListener class if its not the same class,or not loaded with test config
@EmbeddedKafka(partitions = 1, controlledShutdown = false,
brokerProperties = {"listeners=PLAINTEXT://localhost:3333", "port=3333"})
public class KafkaConsumerTest{
@Autowired
KafkaEmbedded kafkaEmbeded;
@Autowired
KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry;
перед аннотацией для метода установки
@Before
public void setUp() throws Exception {
for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry.getListenerContainers()) {
ContainerTestUtils.waitForAssignment(messageListenerContainer,
kafkaEmbeded.getPartitionsPerTopic());
}
}
примечание: Я не использую @ClassRule
для создания встроенной Кафки достаточно авто-проводки @Autowired embeddedKafka
@Test
public void testReceive() throws Exception {
kafkaTemplate.send(topic, data);
}
надеюсь, что это помогает!
Edit: класс конфигурации теста, отмеченный @TestConfiguration
@TestConfiguration
public class TestConfig {
@Bean
public ProducerFactory<String, String> producerFactory() {
return new DefaultKafkaProducerFactory<>(KafkaTestUtils.producerProps(kafkaEmbedded));
}
@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
KafkaTemplate<String, String> kafkaTemplate = new KafkaTemplate<>(producerFactory());
kafkaTemplate.setDefaultTopic(topic);
return kafkaTemplate;
}
теперь @Test
метод будет autowire KafkaTemplate и использовать отправить сообщение
kafkaTemplate.send(topic, data);
обновленный блок кода ответа с вышеуказанной строкой
Я решил проблему сейчас
@BeforeClass
public static void setUpBeforeClass() {
System.setProperty("spring.kafka.bootstrap-servers", embeddedKafka.getBrokersAsString());
System.setProperty("spring.cloud.stream.kafka.binder.zkNodes", embeddedKafka.getZookeeperConnectionString());
}
пока я отлаживал, я видел, что встроенный сервер kaka принимает случайный порт.
Я не смог найти конфигурацию для него, поэтому я устанавливаю конфигурацию Кафки так же, как сервер. Выглядит все еще немного уродливо для меня.
Я хотел бы иметь только упомянутую строку @Mayur " @EmbeddedKafka (partitions = 1, controlledShutdown = false, brokerProperties = {"listeners=PLAINTEXT: / / localhost:9092", "port=9092"}) " но не удается найти правильную зависимость в интернете.