Внедренный Spring-Kafka делает несвязанные юнит-тесты неудачными - PullRequest
0 голосов
/ 18 марта 2019

Spring-Kafka в Сервере памяти запускается со случайного порта. Таким образом, запись application.yml является переменной:

bootstrap-servers: ${spring.embedded.kafka.brokers}

Однако это свойство устанавливается, только когда встроенный сервер Kafka действительно запущен. В модульных тестах без встроенных исключений Kafka генерируются исключения (поскольку переменная фактически не устанавливается):

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'kafkaReceiverConfig': Injection of 
autowired dependencies failed; nested exception is 
java.lang.IllegalArgumentException: Could not resolve placeholder 
spring.embedded.kafka.brokers' in value "${spring.embedded.kafka.brokers}"

Вот класс конфигурации Java:

@Configuration
@EnableKafka
public class KafkaReceiverConfig {

  @Value("${kafka.bootstrap-servers}")
  private String bootstrapServers;

  @Bean
  public KafkaReceiver kafkaReceiver() {
     return new KafkaReceiver();
  }
}

Вдохновение взято от здесь .

Обходной путь - включить встроенный Kafka в каждый модульный тест) -;

Как можно избежать таких радикальных мер?

1 Ответ

3 голосов
/ 18 марта 2019

Всякий раз, когда вы используете @EmbeddedKafka в тестовых классах, вы можете сделать так:

static {
    System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,
            "spring.kafka.bootstrap-servers");
}

Таким образом, EmbeddedKafkaBroker будет выставлять свой адрес со случайным портом непосредственно в spring.kafka.bootstrap-servers. Поэтому вам не понадобится это изменение в application.yml и не понадобится @EmbeddedKafka в других классах.

UPDATE

OK! Не похоже, что вы полагаетесь на автоконфигурацию Spring Boot и ее обычные свойства.

Итак, чтобы SpringKafkaApplicationTest работал, вам нужно иметь системное свойство, подобное этому:

static { System.setProperty (EmbeddedKafkaBroker.BROKER_LIST_PROPERTY, "kafka.bootstrap-серверы"); }

Вам вообще не нужно иметь это свойство kafka.bootstrap-servers в application.yml.

Проблема с SpringJmsApplicationTest в том, что он полностью основан на @SpringBootTest, который собирается загрузить ваш SpringApplication всеми классами @Configuration, которые есть во вложенных пакетах, включая KafkaReceiverConfig и KafkaSenderConfig. Я предполагаю, что вы хотели бы не иметь их в случае SpringJmsApplicationTest. Таким образом, вы должны рассмотреть не загружать все приложение из вашего @SpringBootTest.

Только быстрое решение, которое я вижу для ваших тестов, выглядит так:

@SpringBootTest(classes = { ActiveMqReceiverConfig.class, ActiveMqSenderConfig.class })
public class SpringJmsApplicationTest {

Полагаю, вы можете сделать то же самое для SpringKafkaApplicationTest:

@SpringBootTest(classes = { KafkaReceiverConfig.class, KafkaSenderConfig.class })
@DirtiesContext
@EmbeddedKafka(partitions = 1,
        topics = { SpringKafkaApplicationTest.HELLOWORLD_TOPIC })
public class SpringKafkaApplicationTest {
...