使用不包含DirtiesContext的Testcontainers的kafka进行的春季启动测试

时间:2020-03-18 16:04:43

标签: java spring-boot apache-kafka testcontainers

我的目标是在没有@DirtiesContext的测试中使用具有弹簧启动上下文的kafka测试容器。问题是没有为每个测试类分别启动容器,我不知道如何使用仅由特定测试类或方法生成的消息。 因此,我最终消耗的消息不属于正在运行的测试类。

一种解决方案可能是清除消息主题。我不知道如何执行此操作,我尝试重新启动容器,但接下来的测试无法连接到kafka。

我想到的第二个解决方案是在测试方法的开头创建消费者,并以某种方式记录最新消息,同时将调用其他测试人员。我已经能够使用嵌入式kafka做到这一点,但我不知道如何使用测试容器来做到这一点。

当前配置如下:

@TestConfiguration
public class KafkaContainerConfig {

  @Bean(initMethod = "start", destroyMethod = "stop")
  public KafkaContainer kafkaContainer() {
    return new KafkaContainer("5.0.3");
  }

  @Bean
  public KafkaAdmin kafkaAdmin(KafkaProperties kafkaProperties, KafkaContainer kafkaContainer) {
    kafkaProperties.setBootstrapServers(List.of(kafkaContainer.getBootstrapServers()));
    return new KafkaAdmin(kafkaProperties.buildAdminProperties());
  }

}

带有将提供上述配置的注释

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(KafkaContainerConfig.class)
@EnableAutoConfiguration(exclude = TestSupportBinderAutoConfiguration.class)
@TestPropertySource("classpath:/application-test.properties")
@DirtiesContext
public @interface IncludeKafkaTestContainer {
}

在具有多个此类配置的测试类中,其外观类似于:

@IncludeKafkaTestContainer
@IncludePostgresTestContainer
@SpringBootTest(webEnvironment = RANDOM_PORT)
class SomeTest {
...
}

当前测试方法中的使用者是通过以下方式创建的:

KafkaConsumer<String, String> kafkaConsumer = createKafkaConsumer("topic_name");
ConsumerRecords<String, String> consumerRecords = kafkaConsumer.poll(Duration.ofSeconds(1));
List<ConsumerRecord<String, String>> topicMsgs = Lists.newArrayList(consumerRecords.iterator());

并且:

 public static KafkaConsumer<String, String> createKafkaConsumer(String topicName) {
    Properties properties = new Properties();
    properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
    properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaContainer.getBootstrapServers());
    properties.put(ConsumerConfig.GROUP_ID_CONFIG, "testGroup_" + topicName);
    properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class)

    KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(properties);
    kafkaConsumer.subscribe(List.of(topicName));
    return kafkaConsumer;
}

0 个答案:

没有答案
相关问题