web-dev-qa-db-ja.com

スプリングブートを使用した簡単な埋め込みKafkaテスト例

FYIの編集: 実際のgitHubの例


インターネットを検索していて、埋め込みKafkaテストの実用的で簡単な例を見つけることができませんでした。

セットアップ:

  • 春のブーツ
  • 複数の @ KafkaListener 1つのクラスに異なるトピックがある
  • 埋め込みKafkaは正常に開始されるテスト用
  • トピックに送信するKafkatemplateを使用してテストしますが、 @ KafkaListener メソッドは、大きなスリープ時間の後でも何も受信しません
  • 警告やエラーは表示されません。ログ内のKafkaからの情報スパムのみ

私を助けてください。ほとんどの場合、構成が過剰または過剰に設計された例があります。簡単にできると確信しています。みんなありがとう!

@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
    }
}

private static String SENDER_TOPIC = "test.kafka.topic";

@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);
    }
20
Yuna Braska

埋め込みKafkaテストは以下の設定で動作しますが、

テストクラスの注釈

@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());
  }
}

注:埋め込みKafkaの作成に@ClassRuleを使用しているのではなく、自動配線
@Autowired embeddedKafka

@Test
public void testReceive() throws Exception {
     kafkaTemplate.send(topic, data);
}

お役に立てれば!

編集:@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メソッドはKafkaTemplateを自動配線し、メッセージを送信するために使用します

kafkaTemplate.send(topic, data);

上記の行で更新された応答コードブロック

23
Mayur

今すぐ問題を解決しました

@BeforeClass
public static void setUpBeforeClass() {
    System.setProperty("spring.kafka.bootstrap-servers", embeddedKafka.getBrokersAsString());
    System.setProperty("spring.cloud.stream.kafka.binder.zkNodes", embeddedKafka.getZookeeperConnectionString());
}

デバッグ中に、組み込みのkakaサーバーがランダムなポートを使用していることがわかりました。

その構成が見つからなかったため、サーバーと同じkafka構成を設定しています。私にはまだ少しいようです。

@Mayurに言及した行だけが欲しい

@EmbeddedKafka(partitions = 1, controlledShutdown = false, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"})

しかし、インターネットで適切な依存関係を見つけることができません。

6
Yuna Braska

受け入れられた答えは私にとってはコンパイルも機能もしないので。 https://blog.mimacom.com/testing-Apache-kafka-with-spring-boot/ に基づいた別のソリューションを見つけました。

依存関係は「spring-kafka-test」バージョンです:「2.2.7.RELEASE」

@RunWith(SpringRunner.class)
@EmbeddedKafka(partitions = 1, topics = { "testTopic" })
@SpringBootTest
public class SimpleKafkaTest {

    private static final String TEST_TOPIC = "testTopic";

    @Autowired
    EmbeddedKafkaBroker embeddedKafkaBroker;

    @Test
    public void testReceivingKafkaEvents() {
        Consumer<Integer, String> consumer = configureConsumer();
        Producer<Integer, String> producer = configureProducer();

        producer.send(new ProducerRecord<>(TEST_TOPIC, 123, "my-test-value"));

        ConsumerRecord<Integer, String> singleRecord = KafkaTestUtils.getSingleRecord(consumer, TEST_TOPIC);
        assertThat(singleRecord).isNotNull();
        assertThat(singleRecord.key()).isEqualTo(123);
        assertThat(singleRecord.value()).isEqualTo("my-test-value");

        consumer.close();
        producer.close();
    }

    private Consumer<Integer, String> configureConsumer() {
        Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("testGroup", "true", embeddedKafkaBroker);
        consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        Consumer<Integer, String> consumer = new DefaultKafkaConsumerFactory<Integer, String>(consumerProps)
                .createConsumer();
        consumer.subscribe(Collections.singleton(TEST_TOPIC));
        return consumer;
    }

    private Producer<Integer, String> configureProducer() {
        Map<String, Object> producerProps = new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker));
        return new DefaultKafkaProducerFactory<Integer, String>(producerProps).createProducer();
    }
}
0
LazR