如何使用Spring Kafka测试Kafka Streams应用程序?

时间:2019-08-31 11:30:25

标签: spring-boot apache-kafka apache-kafka-streams spring-kafka spring-kafka-test

我正在用Kafka Streams,Spring-Kafka和Spring Boot编写流应用程序。我找不到任何有关如何在使用Spring-Kafka时正确测试Kafka Streams DSL完成的流处理的信息。文档中提到EmbeddedKafkaBroker,但似乎没有有关如何处理例如状态存储的测试的信息。

仅提供一些我想测试的简单示例。我注册了以下bean(其中avro是在其中生成的):


    @Bean
    public KTable<String, Long> itemTotalKTable(StreamsBuilder streamsBuilder) {
        return streamsBuilder
                .stream(ITEM_TOPIC,
                        Consumed.with(Serdes.String(), itemAvroSerde))
                .mapValues((id, item) -> item.getNumber())
                .groupByKey()
                .aggregate(
                        () -> 0L,
                        (id, number, agg) -> agg + number,
                        Materialized.with(Serdes.String(), Serdes.Long()));
    }

测试所有项目编号是否汇总的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

Spring Kafka for Kafka Streams支持没有带来任何额外的API,特别是在流构建及其处理中。

我们最近为自己打开了一个不错的kafka-streams-test-utils库,可以在没有任何Kafka代理启动(甚至嵌入式)的情况下用于单元测试。

在我们的一些测试中,我们有这样的东西:

    KStream<String, String> stream = builder.stream(INPUT);
    stream
            .transform(() -> enricher)
            .to(OUTPUT);

    Properties config = new Properties();
    config.put(StreamsConfig.APPLICATION_ID_CONFIG, "test");
    config.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9999");
    TopologyTestDriver driver = new TopologyTestDriver(builder.build(), config);

    ConsumerRecordFactory<String, String> recordFactory = new ConsumerRecordFactory<>(new StringSerializer(),
            new StringSerializer());
    driver.pipeInput(recordFactory.create(INPUT, "key", "value"));
    ProducerRecord<byte[], byte[]> result = driver.readOutput(OUTPUT);
    assertThat(result.headers().lastHeader("foo")).isNotNull();

我认为TopologyTestDriver中应该有一些API来处理上述状态存储。

答案 1 :(得分:0)

也许您可以创建一个将KTable作为参数并调用.toStream().to(topicname,Produced.with(keyserde, valueserde))的方法,然后可以执行以下操作:

MyTopologyBuilder builder = new MyTopologyBuilder();

testDriver = new TopologyTestDriver(builder.build(), config);

ConsumerRecord<byte[], byte[]> input = createStepRecord(key, record);

testDriver.pipeInput(input);

ProducerRecord<String, String> out testDriver.readOutput(topic, new StringDeserializer(), ew AvroDeserializer<>(MyClass.class);

assertThat(out.key(), is(key));
assertEquals(myPredefinedValue, out.value());
assertEquals(5, out.value().getMyList().size());

这应该可以,但是我想可能会有更优雅的方式。