{"id":27248875,"url":"https://github.com/bakdata/fluent-kafka-streams-tests","last_synced_at":"2025-04-10T23:48:23.126Z","repository":{"id":38359641,"uuid":"165246903","full_name":"bakdata/fluent-kafka-streams-tests","owner":"bakdata","description":"Fluent Kafka Streams Test with Java","archived":false,"fork":false,"pushed_at":"2025-03-26T15:03:26.000Z","size":614,"stargazers_count":89,"open_issues_count":1,"forks_count":16,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-10T23:48:13.333Z","etag":null,"topics":["avro","java","kafka-streams","test-framework","testing","testing-framework"],"latest_commit_sha":null,"homepage":"https://medium.com/bakdata/fluent-kafka-streams-tests-e641785171ec","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bakdata.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-01-11T13:18:44.000Z","updated_at":"2025-03-20T08:35:47.000Z","dependencies_parsed_at":"2024-02-07T09:37:56.556Z","dependency_job_id":"84ee04b2-b9d7-4f72-b893-03aec56b3f03","html_url":"https://github.com/bakdata/fluent-kafka-streams-tests","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakdata%2Ffluent-kafka-streams-tests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakdata%2Ffluent-kafka-streams-tests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakdata%2Ffluent-kafka-streams-tests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakdata%2Ffluent-kafka-streams-tests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bakdata","download_url":"https://codeload.github.com/bakdata/fluent-kafka-streams-tests/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248317724,"owners_count":21083528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avro","java","kafka-streams","test-framework","testing","testing-framework"],"created_at":"2025-04-10T23:48:22.621Z","updated_at":"2025-04-10T23:48:23.118Z","avatar_url":"https://github.com/bakdata.png","language":"Java","funding_links":[],"categories":["Kafka"],"sub_categories":["Spring Cloud框架"],"readme":"[![Build Status](https://dev.azure.com/bakdata/public/_apis/build/status/bakdata.fluent-kafka-streams-tests?branchName=master)](https://dev.azure.com/bakdata/public/_build/latest?definitionId=2\u0026branchName=master)\n[![Sonarcloud status](https://sonarcloud.io/api/project_badges/measure?project=com.bakdata.fluent-kafka-streams-tests%3Afluent-kafka-streams-tests\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=com.bakdata.fluent-kafka-streams-tests%3Afluent-kafka-streams-tests)\n[![Code coverage](https://sonarcloud.io/api/project_badges/measure?project=com.bakdata.fluent-kafka-streams-tests%3Afluent-kafka-streams-tests\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=com.bakdata.fluent-kafka-streams-tests%3Afluent-kafka-streams-tests)\n[![Maven](https://img.shields.io/maven-central/v/com.bakdata.fluent-kafka-streams-tests/fluent-kafka-streams-tests-junit5.svg)](https://search.maven.org/search?q=g:com.bakdata.fluent-kafka-streams-tests%20AND%20a:fluent-kafka-streams-tests*\u0026core=gav)\n\nFluent Kafka Streams Tests\n=========================\n\nWrite clean and concise tests for your Kafka Streams application.\n\nYou can find a [blog post on medium](https://medium.com/bakdata/fluent-kafka-streams-tests-e641785171ec) with some examples and detailed explanations of how Fluent Kafka Streams Tests work.\n\n## Getting Started\n\nYou can add Fluent Kafka Streams Tests via Maven Central.\n\n#### Gradle\n```gradle\ncompile group: 'com.bakdata.fluent-kafka-streams-tests', name: 'fluent-kafka-streams-tests-junit5', version: '2.1.0'\n```\n\n#### Maven\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.bakdata.fluent-kafka-streams-tests\u003c/groupId\u003e\n    \u003cartifactId\u003efluent-kafka-streams-tests-junit5\u003c/artifactId\u003e\n    \u003cversion\u003e2.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThere is also a junit4 version and one without any dependencies to a specific testing framework.\n\nFor other build tools or versions, refer to the [overview of sonatype](https://search.maven.org/search?q=g:com.bakdata.fluent-kafka-streams-tests%20AND%20a:fluent-kafka-streams-*\u0026core=gav).\n\n## Using it to Write Tests\n\nHere are two example tests which show you how to use Fluent Kafka Streams Tests.\n\n#### Word Count Test\nAssume you have a Word Count Kafka Streams application, called `WordCount`, and want to test it correctly.\nFirst, start by creating a new test class with your application.\n\n```java\nclass WordCountTest {\n    private final WordCount app = new WordCount();\n}\n```\n\nThen, set up the `TestTopology`.\n\n```java\nclass WordCountTest {\n    private final WordCount app = new WordCount();\n\n    @RegisterExtension\n    final TestTopologyExtension\u003cObject, String\u003e testTopology =\n        new TestTopologyExtension\u003c\u003e(this.app::getTopology, this.app.getKafkaProperties());\n}\n```\n\nThe `TestTopology` takes care of all the inputs, processing, and outputs of you application.\nFor it to do that, you need to register it as an extension (JUnit5), so certain setup/teardown methods are called.\nThe constructor expects a topology factory (for a fresh topology in each test) that creates the topology under test.\n\nAdditionally, the properties of the `KafkaClient` need to be specified.\nBroker and application-id must be present (Kafka testutil limitation), but are ignored.\nMost importantly, if the application expects default serde for key and value, these must be present in the properties or\nexplicitly specified with `withDefaultKeySerde(Serde serde)` and/or `withDefaultValueSerde(Serde serde)`.\n\nTo test your appliction, you can simply write a JUnit test.\n```java\nclass WordCountTest {\n    private final WordCount app = new WordCount();\n\n    @RegisterExtension\n    final TestTopologyExtension\u003cObject, String\u003e testTopology =\n        new TestTopologyExtension\u003c\u003e(this.app::getTopology, this.app.getKafkaProperties());\n\n    @Test\n    void shouldAggregateSameWordStream() {\n        this.testTopology.input()\n            .add(\"cat\")\n            .add(\"dog\")\n            .add(\"cat\");\n\n        this.testTopology.streamOutput().withSerde(Serdes.String(), Serdes.Long())\n            .expectNextRecord().hasKey(\"cat\").hasValue(1L)\n            .expectNextRecord().hasKey(\"dog\").hasValue(1L)\n            .expectNextRecord().hasKey(\"cat\").hasValue(2L)\n            .expectNoMoreRecord();\n    }\n}\n```\n\nSee the tests for the [junit4](fluent-kafka-streams-tests-junit4/src/test/java/com/bakdata/fluent_kafka_streams_tests/junit4/WordCountTest.java) and [framework agnostic](fluent-kafka-streams-tests/src/test/java/com/bakdata/fluent_kafka_streams_tests/WordCountTest.java) setup.\n\nThe `TestTopology` has a method `.input()` to retrieve the input topic (or `.input(String topic)`) if more than one input topic is present).\nYou can simply add values to your input stream by calling `.add(V value)` or `.add(K key, V value)`.\n\nTo get the output, `TestTopology` provides two methods: `.streamOutput()` and `.tableOutput()`.\nThey behave just like the input with regard to the number of output topics.\nUsing the stream version simulates Kafka's stream-semantics, meaning that a key can be present many times in an output stream, whereas the table-semantics only output the newest value of each key.\n\nTo check the output records, you can call `.expectNextRecord()` and then chain `.hasKey(K key)`, `.hasKeySatisfying(Consumer\u003cK\u003e requirements)`, `.hasValue(V value)` or `.hasValueSatisfying(Consumer\u003cV\u003e requirements)` to this call.\nNote that calling `.expectNextRecord()` by itself without chaining at least one of the `.has*` methods will not check for the existence of a next record!\n\nOnce you expect no further records, call `.expectNoMoreRecord()` to indicate the end of the output stream.\n\n#### Using Other Test Frameworks to Check Output\nWe intentionally kept the API for output checking slim, because there are many tools out there which focus on doing exactly that.\nThe `TestOutput` class implements the `Iterable` interface, so you can use your favorite tool to test iterables.\n\nHere is an example using [AssertJ](http://joel-costigliola.github.io/assertj/).\n\n```java\n@Test\nvoid shouldReturnCorrectIteratorTable() {\n    this.testTopology.input()\n        .add(\"cat\")\n        .add(\"dog\")\n        .add(\"bird\");\n\n    assertThat(this.testTopology.tableOutput().withSerde(Serdes.String(), Serdes.Long()))\n        .extracting(ProducerRecord::key)\n        .containsAll(List.of(\"cat\", \"dog\", \"bird\"));\n}\n```\n\nThere is also an API to consume a record's key or value in order to embed another assertion framework into our API.\n\n```java\n@Test\nvoid shouldReturnCorrectIteratorTable() {\n    this.testTopology.input()\n        .add(\"cat\");\n\n    this.testTopology.streamOutput().withSerde(Serdes.String(), Serdes.Long())\n            .expectNextRecord()\n            .hasKeySatisfying(key -\u003e assertThat(key).isEqualTo(\"cat\"))\n            .hasValueSatisfying(value -\u003e assertThat(value).isEqualTo(1L))\n            .expectNoMoreRecord();\n}\n```\n\nAlternatively, you can convert the output to `List` for use with your assertion framework. Here is an example of this with [AssertJ](http://joel-costigliola.github.io/assertj/).\n\n```java\n@Test\nvoid shouldConvertStreamOutputToList(){\n    this.testTopology.input()\n        .add(\"cat\")\n        .add(\"dog\")\n        .add(\"bird\");\n\n    final List\u003cProducerRecord\u003cString, Long\u003e\u003eoutputs = this.testTopology.streamOutput()\n        .withSerde(Serdes.String(), Serdes.Long())\n        .toList();\n\n    assertThat(outputs)\n        .extracting(ProducerRecord::key)\n        .containsExactly(\"cat\", \"dog\", \"bird\");\n    assertThat(outputs)\n        .extracting(ProducerRecord::value)\n        .containsExactly(1L, 1L, 1L);\n}\n```\n\n#### More Examples\n\nYou can find many more tests\nin [this repository's test code](https://github.com/bakdata/fluent-kafka-streams-tests/tree/master/fluent-kafka-streams-tests/src/test/java/com/bakdata/fluent_kafka_streams_tests)\n.\n\n## Development\n\nIf you want to contribute to this project, you can simply clone the repository and build it via Gradle.\nAll dependencies should be included in the Gradle files, there are no external prerequisites.\n\n```bash\n\u003e git clone git@github.com:bakdata/fluent-kafka-streams-tests.git\n\u003e cd fluent-kafka-streams-tests \u0026\u0026 ./gradlew build\n```\n\nPlease note, that we have [code styles](https://github.com/bakdata/bakdata-code-styles) for Java.\nThey are basically the Google style guide, with some small modifications.\n\n## Contributing\n\nWe are happy if you want to contribute to this project.\nIf you find any bugs or have suggestions for improvements, please open an issue.\nWe are also happy to accept your PRs.\nJust open an issue beforehand and let us know what you want to do and why.\n\n## License\nThis project is licensed under the MIT license.\nHave a look at the [LICENSE](https://github.com/bakdata/fluent-kafka-streams-tests/blob/master/LICENSE) for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbakdata%2Ffluent-kafka-streams-tests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbakdata%2Ffluent-kafka-streams-tests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbakdata%2Ffluent-kafka-streams-tests/lists"}