私は最近、テストをサポートするJavaライブラリであるtestcontainers-javaに遭遇しました。これは、JUnit
一般的なデータベース、Selenium Webブラウザー、またはDockerコンテナーで実行できるその他のものの軽量で使い捨てのインスタンスを提供します(https://testcontainers.org/をチェックしてください)詳細については!)
これを使用してKafka
、実際のKafka
インスタンスに対してベースのアプリケーションの統合テストを実行できます。このブログでは、このライブラリを使用してKafka Streams
トポロジをテストする方法と、Kafka Streamテストユーティリティクラスを紹介します(以前のブログ投稿で説明しました)。
GitHubで利用可能な例
簡単に言うと、testcontainers-java
ライブラリを使用すると、Dockerコンテナをプログラムで起動できます。もちろん、このような Java Dockerクライアントを直接使用できますがtestcontainers-java
、いくつかの利点と使いやすさが提供されます。唯一の前提条件はDocker自体です
カフカと testcontainers
testcontainers-javaを使用すると、実際のKafkaエージェント(またはクラスター)を起動し、組み込みバージョンの代わりにそれに対して統合テストを実行できます。
まず、GenericContainer
APIを使用してKafkaコンテナーを起動し、たとえば合流のkafka Dockerイメージを使用します。これは次のようになります:
public GenericContainer kafka = new GenericContainer<>("confluentinc/cp-kafka")
.withExposedPorts(9092);
....
String host = kafka.getContainerIpAddress();
Integer port = kafka.getFirstMappedPort();
String bootstrapServer = host+":"+Integer.toString(port)
....
//use the bootstrapServer in tests...
Dockerイメージに基づいてKafkaコンテナーを生成し、ランダムに生成されたポートを取得してローカルコンピューターにマッピングし、ゲームを開始しました。しかし、私たちはもっとうまくやることができます!
Ťestcontainers-java
柔軟性があり、すぐに使用できるモジュールの概念をサポートします。そこ1であるカフカのために利用可能ではすでに、それは物事が少し楽になります。おかげKafkaConŤainer
モジュールは、私たちが行う必要があるすべては私たちがJUnitを使用することができ、たとえばためカフカコンテナを始めるである@Rule
か@ClassRule
のテストを開始する前に始めると、彼らが終了した後に取り壊すますように。
@ClassRule
public KafkaContainer kafka = new KafkaContainer();
...またはさらに制御が必要な場合は、@ Before / @ BeforeClassおよび@ After / @ AfterClassを使用します。
その他の注目すべき点は...
Zookeeper
依存関係を処理する必要はありませんが、モジュールは、必要に応じて外部のモジュールにアクセスするオプションを提供するのに十分な柔軟性があります。例:KafkaContainer kafka = new KafkaContainer().withExternalZookeeper("zk-ext:2181");
- Kafkaクライアントアプリケーションをコンテナ化している場合、それらも
KafkaContainer
インスタンスにアクセスできます - Confluentプラットフォームの特定のバージョンを選択する機能。
new KafkaContainer("5.4.0")
-
Dockerfile
Dockerイメージを参照する代わりにを使用する、DSLを使用してプログラムでビルドするなどのカスタムテクニックDockerfile
例:Kafka Streamsアプリのテストにこれを使用する方法?
Mavenなど、必要な依存関係があることを確認してください
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams-test-utils</artifactId>
<version>2.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>kafka</artifactId>
<version>1.13.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
これは例です:
method-start Kafkaコンテナーを設定する前に@を使用し、Kafka Streamsアプリケーションのブートサーバープロパティを設定する
public class AppTest {
KafkaContainer kafka = new KafkaContainer();
.....
@Before
public void setUp() {
kafka.start();
config = new Properties();
config.setProperty(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers());
config.setProperty(StreamsConfig.APPLICATION_ID_CONFIG, App.APP_ID);
.....
}
これは単純なトポロジです...
static Topology filterWordsLongerThan5Letters() {
StreamsBuilder builder = new StreamsBuilder();
KStream<String, String> stream = builder.stream(INPUT_TOPIC);
stream.filter((k, v) -> v.length() > 5).to(OUTPUT_TOPIC);
return builder.build();
}
...このようにテストできます:
@Test
public void shouldIncludeValueWithLengthGreaterThanFive() {
topology = App.filterWordsLongerThan5Letters();
td = new TopologyTestDriver(topology, config);
inputTopic = td.createInputTopic(App.INPUT_TOPIC, Serdes.String().serializer(), Serdes.String().serializer());
outputTopic = td.createOutputTopic(App.OUTPUT_TOPIC, Serdes.String().deserializer(), Serdes.String().deserializer());
inputTopic.pipeInput("foo", "foobar");
assertThat("output topic was empty", outputTopic.isEmpty(), is(false));
assertThat(outputTopic.readValue(), equalTo("foobar"));
assertThat("output topic was not empty", outputTopic.isEmpty(), is(true));
}
それでおしまい!これは、testcontainers-java
Kafka Streamsテストユーティリティ(GitHubの完全なサンプル)と一緒に使用する方法の例とともに、簡単な紹介です。
から:https://dev.to//itnext/using-docker-to-test-your-kafka-applications-fmm