Consider removing @DirtiesContext necessity for @EmbeddedKafka

See original GitHub issue

Expected Behavior

Hello,

At the moment we are testing a Spring Boot application with en embedded Kafka broker, as described in the documentation. We are using JUnit 5. Our usual test class is

@DirtiesContext
@SpringBootTest(...)
@EmbeddedKafka(...)
class MyTest {
 ...
}

As described in the documentation we need to add @DirtiesContext on the class specifically for the Kafka broker. This feels a bit wrong, as it resets the whole test application context, and not only the Kafka broker. It is also a pain point for the tests’ execution time, as resetting and recreating the context for multiple test classes may be long.

It would be great if the behavior would be similar to the one found for instance with WebTestClientContextCustomizer, which does not need to have a context reset.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
celcius112commented, May 9, 2022

Thank you for the careful and detailed explanation, I found my solution with the third proposition.

For future reference, here’s what I ended up doing:

  1. I created a JUnit 5 extension that initializes the kafka broker. This initialization is done only once per test suite, and only if at least one test uses the extension, so that if we launch tests that do not require a spring context we do not create the kafka broker for nothing:
public class KafkaBrokerExtension implements BeforeAllCallback {

  private static EmbeddedKafkaBroker embeddedKafkaBroker;

  @Override
  public void beforeAll(ExtensionContext extensionContext) {
    if (embeddedKafkaBroker == null) {
      embeddedKafkaBroker = buildEmbeddedKafkaBroker();
    }
  }

  private static EmbeddedKafkaBroker buildEmbeddedKafkaBroker() {
    EmbeddedKafkaBroker embeddedKafkaBroker = new EmbeddedKafkaBroker(1)
        .brokerProperties(Map.of("listeners", "PLAINTEXT://localhost:9092"));
    embeddedKafkaBroker.afterPropertiesSet();
    return embeddedKafkaBroker;
  }
}
  1. I also created a TestExecutionListener using the selfsame extension (see https://junit.org/junit5/docs/current/user-guide/#launcher-api-listeners-custom) that destroys the broker, if it exists, when all tests are executed:
public class KafkaBrokerExtension implements TestExecutionListener {
 ...  
  @Override
  public void testPlanExecutionFinished(TestPlan testPlan) {
    KafkaBrokerExtension.getEmbeddedKafkaBroker().ifPresent(EmbeddedKafkaBroker::destroy);
  }
}

It’s not a perfect solution (I don’t like static initializers) but we improved the build time by 20%.

0reactions
artembilancommented, May 10, 2022

Well, then extension you suggest is not consistent: it may start the broker in a first test, but it is not going to be stopped until the end of the plan. When only that first class is interested in such a broker. I know that my testPlanExecutionStarted() is too drastic, but at least it is very clean what is going on around the whole test plan.

This Embedded Kafka was really designed for individual test cases, for different Kafka environment, different number of brokers etc. What you are talking about is more like a single Kafka instance which is better to manage outside of the project test plan. Your suggestion is just a bit of an anti-pattern for Unit paradigms.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is the proper way of doing @DirtiesConfig when used ...
But if I remove all @DirtiesContext, and clear db manually and commit changes, so that after each test the changes are reverted, everything ......
Read more >
spring-projects/spring-kafka - Gitter
I think if I create another class similar to this one - the embeddedKafka bean ... class and really have @DirtiesContext to close...
Read more >
Testing Kafka and Spring Boot - Baeldung
Now that we have all the necessary dependencies configured, we can write a simple Spring Boot application using Kafka.
Read more >
Testing Spring Embedded Kafka consumer and producer
@ DirtiesContext – test annotation which indicates that the ApplicationContext associated with a test is dirty and should therefore be closed ...
Read more >
Spring for Apache Kafka
2.1.8 Embedded Kafka Changes. The KafkaEmbedded class and its KafkaRule interface have need deprecated in favor of the EmbeddedKafkaBroker and its JUnit 4 ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found