From f8d53b4c6015d5646c74320151c1ee235f059967 Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Thu, 17 Sep 2020 22:00:57 +0200 Subject: [PATCH 1/5] BAEL-4437 - System Rules --- testing-modules/pom.xml | 3 +- testing-modules/testing-libraries-2/pom.xml | 43 ++++++++++++++++++ ...ClearSystemPropertiesWithRuleUnitTest.java | 19 ++++++++ .../ProvidesSystemPropertyUnitTest.java | 26 +++++++++++ ...rovidesSystemPropertyWithRuleUnitTest.java | 44 +++++++++++++++++++ .../systemrules/SystemErrPrintlnUnitTest.java | 24 ++++++++++ .../SystemErrPrintlnWithRuleUnitTest.java | 25 +++++++++++ .../systemrules/SystemExitUnitTest.java | 23 ++++++++++ .../SystemExitWithRuleUnitTest.java | 22 ++++++++++ .../systemrules/SystemInUnitTest.java | 27 ++++++++++++ .../systemrules/SystemInWithRuleUnitTest.java | 31 +++++++++++++ .../src/test/resources/test.properties | 2 + 12 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 testing-modules/testing-libraries-2/pom.xml create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ClearSystemPropertiesWithRuleUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyWithRuleUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnWithRuleUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitWithRuleUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInWithRuleUnitTest.java create mode 100644 testing-modules/testing-libraries-2/src/test/resources/test.properties diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index f1d30cd7a1..0416423239 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -41,7 +41,8 @@ junit-5-advanced xmlunit-2 junit-4 - testing-libraries + testing-libraries + testing-libraries-2 powermock diff --git a/testing-modules/testing-libraries-2/pom.xml b/testing-modules/testing-libraries-2/pom.xml new file mode 100644 index 0000000000..282583c882 --- /dev/null +++ b/testing-modules/testing-libraries-2/pom.xml @@ -0,0 +1,43 @@ + + 4.0.0 + testing-libraries-2 + testing-libraries-2 + + + com.baeldung + testing-modules + 1.0.0-SNAPSHOT + + + + + com.github.stefanbirkner + system-rules + ${system-rules.version} + test + + + com.github.stefanbirkner + system-lambda + ${system-lambda.version} + test + + + + + testing-libraries + + + src/test/resources + true + + + + + + 1.19.0 + 1.0.0 + + diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ClearSystemPropertiesWithRuleUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ClearSystemPropertiesWithRuleUnitTest.java new file mode 100644 index 0000000000..699b40bad9 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ClearSystemPropertiesWithRuleUnitTest.java @@ -0,0 +1,19 @@ +package com.baeldung.systemrules; + +import static org.junit.Assert.assertNull; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.ClearSystemProperties; + +public class ClearSystemPropertiesWithRuleUnitTest { + + @Rule + public final ClearSystemProperties userNameIsClearedRule = new ClearSystemProperties("user.name"); + + @Test + public void givenClearUsernameProperty_whenGetUserName_thenNull() { + assertNull(System.getProperty("user.name")); + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyUnitTest.java new file mode 100644 index 0000000000..361a338508 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.systemrules; + +import static com.github.stefanbirkner.systemlambda.SystemLambda.restoreSystemProperties; +import static org.junit.Assert.assertEquals; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ProvidesSystemPropertyUnitTest { + + @BeforeAll + static void setUpBeforeClass() throws Exception { + System.setProperty("log_dir", "/tmp/baeldung/logs"); + } + + @Test + void givenSetSystemProperty_whenGetLogDir_thenLogDirIsProvidedSuccessfully() throws Exception { + restoreSystemProperties(() -> { + System.setProperty("log_dir", "test/resources"); + assertEquals("log_dir should be provided", "test/resources", System.getProperty("log_dir")); + }); + + assertEquals("log_dir should be provided", "/tmp/baeldung/logs", System.getProperty("log_dir")); + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyWithRuleUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyWithRuleUnitTest.java new file mode 100644 index 0000000000..3a90592a0d --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/ProvidesSystemPropertyWithRuleUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.systemrules; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.ProvideSystemProperty; + +public class ProvidesSystemPropertyWithRuleUnitTest { + + @Rule + public final ProvideSystemProperty providesSystemPropertyRule = new ProvideSystemProperty("log_dir", "test/resources").and("another_property", "another_value"); + + @Rule + public final ProvideSystemProperty providesSystemPropertyFromFileRule = ProvideSystemProperty.fromResource("/test.properties"); + + @BeforeClass + public static void setUpBeforeClass() { + setLogs(); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + System.out.println(System.getProperty("log_dir")); + } + + @Test + public void givenProvideSystemProperty_whenGetLogDir_thenLogDirIsProvidedSuccessfully() { + assertEquals("log_dir should be provided", "test/resources", System.getProperty("log_dir")); + } + + @Test + public void givenProvideSystemPropertyFromFile_whenGetName_thenNameIsProvidedSuccessfully() { + assertEquals("name should be provided", "baeldung", System.getProperty("name")); + assertEquals("version should be provided", "1.0", System.getProperty("version")); + } + + private static void setLogs() { + System.setProperty("log_dir", "/tmp/baeldung/logs"); + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnUnitTest.java new file mode 100644 index 0000000000..3345ddae8a --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.systemrules; + +import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemErr; + +import org.junit.Assert; +import org.junit.jupiter.api.Test; + +class SystemErrPrintlnUnitTest { + + @Test + void givenTapSystemErr_whenInvokePrintln_thenOutputIsReturnedSuccessfully() throws Exception { + + String text = tapSystemErr(() -> { + printError("An error occurred Baeldung Readers!!"); + }); + + Assert.assertEquals("An error occurred Baeldung Readers!!", text.trim()); + } + + private void printError(String output) { + System.err.println(output); + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnWithRuleUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnWithRuleUnitTest.java new file mode 100644 index 0000000000..7994f91063 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemErrPrintlnWithRuleUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.systemrules; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.SystemErrRule; + +public class SystemErrPrintlnWithRuleUnitTest { + + @Rule + public final SystemErrRule systemErrRule = new SystemErrRule().enableLog(); + + @Test + public void givenSystemErrRule_whenInvokePrintln_thenLogSuccess() { + printError("An Error occurred Baeldung Readers!!"); + + Assert.assertEquals("An Error occurred Baeldung Readers!!", systemErrRule.getLog() + .trim()); + } + + private void printError(String output) { + System.err.println(output); + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitUnitTest.java new file mode 100644 index 0000000000..1e2548e714 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.systemrules; + +import static org.junit.Assert.assertEquals; + +import static com.github.stefanbirkner.systemlambda.SystemLambda.catchSystemExit; + +import org.junit.jupiter.api.Test; + +class SystemExitUnitTest { + + @Test + void givenCatchSystemExit_whenAppCallsSystemExit_thenStatusIsReturnedSuccessfully() throws Exception { + int statusCode = catchSystemExit(() -> { + exit(); + }); + assertEquals("status code should be 1:", 1, statusCode); + } + + private void exit() { + System.exit(1); + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitWithRuleUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitWithRuleUnitTest.java new file mode 100644 index 0000000000..471aab1989 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemExitWithRuleUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.systemrules; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.ExpectedSystemExit; + +public class SystemExitWithRuleUnitTest { + + @Rule + public final ExpectedSystemExit exitRule = ExpectedSystemExit.none(); + + @Test + public void givenSystemExitRule_whenAppCallsSystemExit_thenExitRuleWorkssAsExpected() { + exitRule.expectSystemExitWithStatus(1); + exit(); + } + + private void exit() { + System.exit(1); + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInUnitTest.java new file mode 100644 index 0000000000..96badb59d4 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.systemrules; + +import static com.github.stefanbirkner.systemlambda.SystemLambda.withTextFromSystemIn; +import static org.junit.Assert.assertEquals; + +import java.util.Scanner; + +import org.junit.jupiter.api.Test; + +class SystemInUnitTest { + + @Test + void givenTwoNames_whenSystemInMock_thenNamesJoinedTogether() throws Exception { + withTextFromSystemIn("Jonathan", "Cook").execute(() -> { + assertEquals("Names should be concatenated", "Jonathan Cook", getFullname()); + }); + } + + private String getFullname() { + try (Scanner scanner = new Scanner(System.in)) { + String firstName = scanner.next(); + String surname = scanner.next(); + return String.join(" ", firstName, surname); + } + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInWithRuleUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInWithRuleUnitTest.java new file mode 100644 index 0000000000..5730e2f592 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/systemrules/SystemInWithRuleUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.systemrules; + +import static org.junit.Assert.assertEquals; + +import java.util.Scanner; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.TextFromStandardInputStream; +import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.emptyStandardInputStream; + +public class SystemInWithRuleUnitTest { + + @Rule + public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); + + @Test + public void givenTwoNames_whenSystemInMock_thenNamesJoinedTogether() { + systemInMock.provideLines("Jonathan", "Cook"); + assertEquals("Names should be concatenated", "Jonathan Cook", getFullname()); + } + + private String getFullname() { + try (Scanner scanner = new Scanner(System.in)) { + String firstName = scanner.next(); + String surname = scanner.next(); + return String.join(" ", firstName, surname); + } + } + +} diff --git a/testing-modules/testing-libraries-2/src/test/resources/test.properties b/testing-modules/testing-libraries-2/src/test/resources/test.properties new file mode 100644 index 0000000000..144847cdb0 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/resources/test.properties @@ -0,0 +1,2 @@ +name=baeldung +version=1.0 \ No newline at end of file From eb3631f36f8e6ab3728b3faffe4169988f84c914 Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Sun, 8 Nov 2020 13:23:31 +0100 Subject: [PATCH 2/5] BAEL-4687 Testing Kafka and Spring Boot --- spring-kafka/pom.xml | 20 ++- .../kafka/embedded/KafkaConsumer.java | 39 ++++++ .../kafka/embedded/KafkaProducer.java | 22 +++ .../KafkaProducerConsumerApplication.java | 15 ++ .../com/baeldung/SpringContextLiveTest.java | 17 --- .../com/baeldung/SpringContextManualTest.java | 17 --- .../EmbeddedKafkaIntegrationTest.java | 55 ++++++++ .../KafkaTestContainersIntegrationTest.java | 132 ++++++++++++++++++ .../src/test/resources/application.yml | 7 + spring-kafka/src/test/resources/logback.xml | 13 ++ 10 files changed, 297 insertions(+), 40 deletions(-) create mode 100644 spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java create mode 100644 spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java create mode 100644 spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java delete mode 100644 spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java delete mode 100644 spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java create mode 100644 spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java create mode 100644 spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java create mode 100644 spring-kafka/src/test/resources/application.yml create mode 100644 spring-kafka/src/test/resources/logback.xml diff --git a/spring-kafka/pom.xml b/spring-kafka/pom.xml index 2b4a0914e6..3673fe8fa5 100644 --- a/spring-kafka/pom.xml +++ b/spring-kafka/pom.xml @@ -1,9 +1,9 @@ - + 4.0.0 spring-kafka - 0.0.1-SNAPSHOT spring-kafka Intro to Kafka with Spring @@ -15,21 +15,29 @@ - org.springframework.boot spring-boot-starter - org.springframework.kafka spring-kafka - com.fasterxml.jackson.core jackson-databind + + org.springframework.kafka + spring-kafka-test + test + + + org.testcontainers + kafka + test + 1.15.0-rc2 + diff --git a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java new file mode 100644 index 0000000000..48a194b4e3 --- /dev/null +++ b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaConsumer.java @@ -0,0 +1,39 @@ +package com.baeldung.kafka.embedded; + +import java.util.concurrent.CountDownLatch; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class KafkaConsumer { + + private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumer.class); + + private CountDownLatch latch = new CountDownLatch(1); + private String payload = null; + + @KafkaListener(topics = "${test.topic}") + public void receive(ConsumerRecord consumerRecord) { + LOGGER.info("received payload='{}'", consumerRecord.toString()); + setPayload(consumerRecord.toString()); + latch.countDown(); + } + + public CountDownLatch getLatch() { + return latch; + } + + public String getPayload() { + return payload; + } + + private void setPayload(String payload) { + this.payload = payload; + } + +} diff --git a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java new file mode 100644 index 0000000000..d7cbd35011 --- /dev/null +++ b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducer.java @@ -0,0 +1,22 @@ +package com.baeldung.kafka.embedded; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +@Component +public class KafkaProducer { + + private static final Logger LOGGER = LoggerFactory.getLogger(KafkaProducer.class); + + @Autowired + private KafkaTemplate kafkaTemplate; + + public void send(String topic, String payload) { + LOGGER.info("sending payload='{}' to topic='{}'", payload, topic); + kafkaTemplate.send(topic, payload); + } + +} diff --git a/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java new file mode 100644 index 0000000000..bf14251d75 --- /dev/null +++ b/spring-kafka/src/main/java/com/baeldung/kafka/embedded/KafkaProducerConsumerApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.kafka.embedded; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +@EnableAutoConfiguration +public class KafkaProducerConsumerApplication { + + public static void main(String[] args) { + SpringApplication.run(KafkaProducerConsumerApplication.class, args); + } + +} diff --git a/spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java b/spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java deleted file mode 100644 index 60262df9d4..0000000000 --- a/spring-kafka/src/test/java/com/baeldung/SpringContextLiveTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import com.baeldung.spring.kafka.KafkaApplication; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = KafkaApplication.class) -public class SpringContextLiveTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java b/spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java deleted file mode 100644 index 0d2c19136f..0000000000 --- a/spring-kafka/src/test/java/com/baeldung/SpringContextManualTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -import com.baeldung.spring.kafka.KafkaApplication; - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = KafkaApplication.class) -public class SpringContextManualTest { - - @Test - public void whenSpringContextIsBootstrapped_thenNoExceptions() { - } -} diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java new file mode 100644 index 0000000000..49ea080369 --- /dev/null +++ b/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.kafka.embedded; + +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.concurrent.TimeUnit; + +@RunWith(SpringRunner.class) +@SpringBootTest +@DirtiesContext +@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" }) +class EmbeddedKafkaIntegrationTest { + + @Autowired + public KafkaTemplate template; + + @Autowired + private KafkaConsumer consumer; + + @Autowired + private KafkaProducer producer; + + @Value("${test.topic}") + private String topic; + + @Test + public void givenEmbeddedKafkaBroker_whenSendingtoDefaultTemplate_thenMessageReceived() throws Exception { + template.send(topic, "Sending with default template"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + + @Test + public void givenEmbeddedKafkaBroker_whenSendingtoSimpleProducer_thenMessageReceived() throws Exception { + producer.send(topic, "Sending with own controller"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + +} diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java new file mode 100644 index 0000000000..cf941b770f --- /dev/null +++ b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java @@ -0,0 +1,132 @@ +package com.baeldung.kafka.testcontainers; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; +import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.utility.DockerImageName; + +import com.baeldung.kafka.embedded.KafkaConsumer; +import com.baeldung.kafka.embedded.KafkaProducer; +import com.baeldung.kafka.embedded.KafkaProducerConsumerApplication; + +@RunWith(SpringRunner.class) +@Import(com.baeldung.kafka.testcontainers.KafkaTestContainersIntegrationTest.KafkaTestContainersConfiguration.class) +@SpringBootTest(classes = KafkaProducerConsumerApplication.class) +@DirtiesContext +public class KafkaTestContainersIntegrationTest { + + @ClassRule + public static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:5.4.3")); + + @Autowired + public KafkaTemplate template; + + @Autowired + private KafkaConsumer consumer; + + @Autowired + private KafkaProducer producer; + + @Value("${test.topic}") + private String topic; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + kafka.start(); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + kafka.stop(); + } + + @Test + public void givenKafkaDockerContainer_whenSendingtoDefaultTemplate_thenMessageReceived() throws Exception { + template.send(topic, "Sending with default template"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + + @Test + public void givenKafkaDockerContainer_whenSendingtoSimpleProducer_thenMessageReceived() throws Exception { + producer.send(topic, "Sending with own controller"); + consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); + + assertThat(consumer.getLatch().getCount(), equalTo(0L)); + assertThat(consumer.getPayload(), containsString("embedded-test-topic")); + } + + @TestConfiguration + static class KafkaTestContainersConfiguration { + + @Bean + ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + return factory; + } + + @Bean + public ConsumerFactory consumerFactory() { + return new DefaultKafkaConsumerFactory<>(consumerConfigs()); + } + + @Bean + public Map consumerConfigs() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers()); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "baeldung"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + return props; + } + + @Bean + public ProducerFactory producerFactory() { + Map configProps = new HashMap<>(); + configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers()); + configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + return new DefaultKafkaProducerFactory<>(configProps); + } + + @Bean + public KafkaTemplate kafkaTemplate() { + return new KafkaTemplate<>(producerFactory()); + } + + } + +} diff --git a/spring-kafka/src/test/resources/application.yml b/spring-kafka/src/test/resources/application.yml new file mode 100644 index 0000000000..7d7997c6fd --- /dev/null +++ b/spring-kafka/src/test/resources/application.yml @@ -0,0 +1,7 @@ +spring: + kafka: + consumer: + auto-offset-reset: earliest + group-id: baeldung +test: + topic: embedded-test-topic \ No newline at end of file diff --git a/spring-kafka/src/test/resources/logback.xml b/spring-kafka/src/test/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-kafka/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file From a51e034186bc8f730dbfbe9cc2230ccf7a47606a Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Fri, 13 Nov 2020 16:42:33 +0100 Subject: [PATCH 3/5] BAEL-4609 - Testing Kafka and Spring Boot --- spring-kafka/pom.xml | 7 +++++-- .../EmbeddedKafkaIntegrationTest.java | 21 ++++++++----------- .../KafkaTestContainersIntegrationTest.java | 12 ----------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/spring-kafka/pom.xml b/spring-kafka/pom.xml index 3673fe8fa5..235dd75966 100644 --- a/spring-kafka/pom.xml +++ b/spring-kafka/pom.xml @@ -22,6 +22,7 @@ org.springframework.kafka spring-kafka + ${spring-kafka.version} com.fasterxml.jackson.core @@ -30,18 +31,20 @@ org.springframework.kafka spring-kafka-test + ${spring-kafka.version} test org.testcontainers kafka + ${testcontainers-kafka.version} test - 1.15.0-rc2 - 2.3.7.RELEASE + 2.5.8.RELEASE + 1.15.0 \ No newline at end of file diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java index 49ea080369..4c727795c4 100644 --- a/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java +++ b/spring-kafka/src/test/java/com/baeldung/kafka/embedded/EmbeddedKafkaIntegrationTest.java @@ -1,22 +1,19 @@ package com.baeldung.kafka.embedded; -import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; import java.util.concurrent.TimeUnit; -@RunWith(SpringRunner.class) +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; + @SpringBootTest @DirtiesContext @EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" }) @@ -45,7 +42,7 @@ class EmbeddedKafkaIntegrationTest { @Test public void givenEmbeddedKafkaBroker_whenSendingtoSimpleProducer_thenMessageReceived() throws Exception { - producer.send(topic, "Sending with own controller"); + producer.send(topic, "Sending with our own simple KafkaProducer"); consumer.getLatch().await(10000, TimeUnit.MILLISECONDS); assertThat(consumer.getLatch().getCount(), equalTo(0L)); diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java index cf941b770f..972b6cce4d 100644 --- a/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java +++ b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java @@ -12,8 +12,6 @@ import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.common.serialization.StringDeserializer; import org.apache.kafka.common.serialization.StringSerializer; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; @@ -59,16 +57,6 @@ public class KafkaTestContainersIntegrationTest { @Value("${test.topic}") private String topic; - @BeforeClass - public static void setUpBeforeClass() throws Exception { - kafka.start(); - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - kafka.stop(); - } - @Test public void givenKafkaDockerContainer_whenSendingtoDefaultTemplate_thenMessageReceived() throws Exception { template.send(topic, "Sending with default template"); From a26085b2660202ba8ff20f2c31b600da6a4d05eb Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Wed, 18 Nov 2020 08:30:49 +0100 Subject: [PATCH 4/5] BAEL-4706 - Spring Boot with Spring Batch - Rename testcontainers test to LiveTest --- ...inersIntegrationTest.java => KafkaTestContainersLiveTest.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/{KafkaTestContainersIntegrationTest.java => KafkaTestContainersLiveTest.java} (100%) diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersLiveTest.java similarity index 100% rename from spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersIntegrationTest.java rename to spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersLiveTest.java From 8e477f4d9c8aa91102c3e47bc493c78243c08580 Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Wed, 18 Nov 2020 10:00:24 +0100 Subject: [PATCH 5/5] BAEL-4706 - Spring Boot with Spring Batch - Rename testcontainers test to LiveTest --- .../testcontainers/KafkaTestContainersLiveTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersLiveTest.java b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersLiveTest.java index 972b6cce4d..74d6f824b1 100644 --- a/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersLiveTest.java +++ b/spring-kafka/src/test/java/com/baeldung/kafka/testcontainers/KafkaTestContainersLiveTest.java @@ -36,11 +36,18 @@ import com.baeldung.kafka.embedded.KafkaConsumer; import com.baeldung.kafka.embedded.KafkaProducer; import com.baeldung.kafka.embedded.KafkaProducerConsumerApplication; +/** + * This test class uses Testcontainers to instantiate and manage an external Apache + * Kafka broker hosted inside a Docker container. + * + * Therefore, one of the prerequisites for using Testcontainers is that Docker is installed on the host running this test + * + */ @RunWith(SpringRunner.class) -@Import(com.baeldung.kafka.testcontainers.KafkaTestContainersIntegrationTest.KafkaTestContainersConfiguration.class) +@Import(com.baeldung.kafka.testcontainers.KafkaTestContainersLiveTest.KafkaTestContainersConfiguration.class) @SpringBootTest(classes = KafkaProducerConsumerApplication.class) @DirtiesContext -public class KafkaTestContainersIntegrationTest { +public class KafkaTestContainersLiveTest { @ClassRule public static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:5.4.3"));