0

the Spring-Kafka in memory Server is started with a random port. As such the application.yml entry is a variable:

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

However, this property is only set when the embedded Kafka server is actually run. In unit tests without the embedded Kafka exceptions are thrown (because the variable is not actually being set):

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

Here is the Java configuration class:

@Configuration
@EnableKafka
public class KafkaReceiverConfig {

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

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

Inspiration is taken from here.

Workaround for now is to include the embedded Kafka into every unit test )-;

How can such drastic measures be avoided ?

1 Answer 1

4

Whenever you use an @EmbeddedKafka in the test classes, you can do like this:

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

So, this way the EmbeddedKafkaBroker will expose its address with a random port into the spring.kafka.bootstrap-servers directly. Therefore you won't need that change in the application.yml and won't need an @EmbeddedKafka in other classes.

UPDATE

OK! Doesn't look like you rely on the Spring Boot auto-configuration and its conventional properties.

So, to make a SpringKafkaApplicationTest working you need to have that system property like this:

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

You don't need to have that kafka.bootstrap-servers property in the application.yml at all.

The problem with the SpringJmsApplicationTest that it is fully based on the @SpringBootTest which is going to load your SpringApplication with all the @Configuration classes you have in the nested packages, including KafkaReceiverConfig and KafkaSenderConfig. I assume you would like do not have them in case of SpringJmsApplicationTest. So, you should consider do not load the whole application from your @SpringBootTest.

Only a quick solution I see for your tests is like this:

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

I guess you can do the same for the SpringKafkaApplicationTest as well:

@SpringBootTest(classes = { KafkaReceiverConfig.class, KafkaSenderConfig.class })
@DirtiesContext
@EmbeddedKafka(partitions = 1,
        topics = { SpringKafkaApplicationTest.HELLOWORLD_TOPIC })
public class SpringKafkaApplicationTest {
Sign up to request clarification or add additional context in comments.

3 Comments

Unfortunately i can't seem to get it to work like that. Please see repo: link
See an UPDATE in my answer.
Thank you so much for your kind help! Got it working now. repo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.