Spring Kafka嵌入式测试

时间:2018-11-06 20:40:12

标签: spring-kafka

我正在使用嵌入式kafka编写一个junit测试用例。我们有一条管道,其中生产者>主题>消费者>做work()>产生。  我正在使用第三方架构注册表(通过提供伪造的url进行模拟测试)以及与之绑定的特定Serdes。在kafka用户组上讨论此方法后,使用 一个模拟注册表,用于手动序列化数据,并在生产者中传递byte []本身,而不是在avro记录中传递。在这种情况下,我的用户为何会失败,因为它期望特定的记录有效负载。有关如何解决此问题的任何想法?

//Listener method


    */
        @KafkaListener(topics = test1,id="tesId1")
        public void onMessage(@Payload Log log, 
                @Header(KafkaHeaders.RECEIVED_PARTITION_ID) int partition,
                @Header(KafkaHeaders.OFFSET) Long offset) throws Exception
                 {

               }


    // test class
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @DirtiesContext
    @EmbeddedKafka(topics = { "test1" })
    @TestPropertySource(properties = { "spring.kafka.bootstrap-servers=${spring.embedded.kafka.brokers}" })
    public class ConsumerTests {

    }

1 个答案:

答案 0 :(得分:1)

只需使用原始的KafkaTemplate(无泛型)和字节数组序列化器即可。

例如,使用JSON和StringSerializer

@SpringBootApplication
public class So53179695Application {

    public static void main(String[] args) {
        SpringApplication.run(So53179695Application.class, args);
    }

    @Bean
    public RecordMessageConverter converter() {
        return new StringJsonMessageConverter();
    }

    @KafkaListener(id = "foo", topics = "foo")
    public void listen(Foo in) {
        System.out.println(in);
    }

    public static class Foo {

        private String bar;

        public Foo() {
            super();
        }

        Foo(String bar) {
            this.bar = bar;
        }

        public String getBar() {
            return this.bar;
        }

        public void setBar(String bar) {
            this.bar = bar;
        }

        @Override
        public String toString() {
            return "Foo [bar=" + this.bar + "]";
        }

    }

}

@RunWith(SpringRunner.class)
@SpringBootTest
public class So53179695ApplicationTests {

    @ClassRule
    public static EmbeddedKafkaRule embeddedKafka = 
        new EmbeddedKafkaRule(1, false, "foo");

    @BeforeClass
    public static void setup() {
        System.setProperty("spring.kafka.bootstrap-servers",
            embeddedKafka.getEmbeddedKafka().getBrokersAsString());
    }

    @Autowired
    public KafkaTemplate<String, Foo> template;

    @SuppressWarnings("rawtypes")
    @Autowired
    public KafkaTemplate rawTemplate;

    @SuppressWarnings("unchecked")
    @Test
    public void test() throws Exception {
//      template.send("foo", new Foo("bar"));
        rawTemplate.send("foo", "{\"bar\":\"baz\"}");
        Thread.sleep(10_000);
    }

}

Foo [bar=baz]

请注意,两个模板都指向同一个物理对象-由于Java的类型擦除,因此在运行时无关紧要。

这假设您在使用者端仍在使用Avro解串器(在此示例中为JSON)。

或者您可以在用户端使用模拟解串器来创建Log