{"id":13697775,"url":"https://github.com/jpzk/mockedstreams","last_synced_at":"2026-01-14T01:50:45.384Z","repository":{"id":55001127,"uuid":"69183604","full_name":"jpzk/mockedstreams","owner":"jpzk","description":"Scala DSL for Unit-Testing Processing Topologies in Kafka Streams","archived":false,"fork":false,"pushed_at":"2021-01-16T10:58:04.000Z","size":21016,"stargazers_count":186,"open_issues_count":7,"forks_count":24,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-06-07T23:52:40.570Z","etag":null,"topics":["kafka","kafka-streams","mocked-streams","scala","testing","topology","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jpzk.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}},"created_at":"2016-09-25T18:48:50.000Z","updated_at":"2025-02-13T20:03:38.000Z","dependencies_parsed_at":"2022-08-14T08:40:44.379Z","dependency_job_id":null,"html_url":"https://github.com/jpzk/mockedstreams","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/jpzk/mockedstreams","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpzk%2Fmockedstreams","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpzk%2Fmockedstreams/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpzk%2Fmockedstreams/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpzk%2Fmockedstreams/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jpzk","download_url":"https://codeload.github.com/jpzk/mockedstreams/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpzk%2Fmockedstreams/sbom","scorecard":{"id":536331,"data":{"date":"2025-08-11","repo":{"name":"github.com/jpzk/mockedstreams","commit":"0dd44731ab9f71a025a99e10c2719f6ee92a3f1e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 1/12 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/scala.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scala.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/jpzk/mockedstreams/scala.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scala.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/jpzk/mockedstreams/scala.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 24 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T07:04:36.023Z","repository_id":55001127,"created_at":"2025-08-20T07:04:36.023Z","updated_at":"2025-08-20T07:04:36.023Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408691,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T00:40:43.272Z","status":"ssl_error","status_checked_at":"2026-01-14T00:40:42.636Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["kafka","kafka-streams","mocked-streams","scala","testing","topology","unit-testing"],"created_at":"2024-08-02T18:01:02.657Z","updated_at":"2026-01-14T01:50:45.378Z","avatar_url":"https://github.com/jpzk.png","language":"Scala","funding_links":[],"categories":["Libraries","Development","Testing","Kafka"],"sub_categories":["Kafka Streams","Testing","Spring Cloud框架"],"readme":"# Mocked Streams \n\n[![Build Status](https://travis-ci.org/jpzk/mockedstreams.svg?branch=master)](https://travis-ci.org/jpzk/mockedstreams)   [![Codacy Badge](https://api.codacy.com/project/badge/Grade/8abac3d072e54fa3a13dc3da04754c7b)](https://www.codacy.com/app/jpzk/mockedstreams?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=jpzk/mockedstreams\u0026amp;utm_campaign=Badge_Grade)\n[![codecov](https://codecov.io/gh/jpzk/mockedstreams/branch/master/graph/badge.svg)](https://codecov.io/gh/jpzk/mockedstreams) [![License](http://img.shields.io/:license-Apache%202-grey.svg)](http://www.apache.org/licenses/LICENSE-2.0.txt) [![GitHub stars](https://img.shields.io/github/stars/jpzk/mockedstreams.svg?style=flat)](https://github.com/jpzk/mockedstreams/stargazers) \n[![Maven Central](https://img.shields.io/maven-central/v/com.madewithtea/mockedstreams_2.12.svg)](http://search.maven.org/#search%7Cga%7C1%7Cmockedstreams) \n\nDocumentation located at http://mockedstreams.madewithtea.com/\n\nMocked Streams 3.9.0 [(git)](https://github.com/jpzk/mockedstreams) is a library for Scala 2.12 and 2.13 which allows you to **unit-test processing topologies** of [Kafka Streams](https://kafka.apache.org/documentation#streams) applications (since Apache Kafka \u003e=0.10.1) **without Zookeeper and Kafka Brokers**. Further, you can use your favourite Scala testing framework e.g. [ScalaTest](http://www.scalatest.org/) and [Specs2](https://etorreborre.github.io/specs2/). Mocked Streams is located at the Maven Central Repository, therefore you just have to add the following to your [SBT dependencies](http://www.scala-sbt.org/0.13/docs/Library-Dependencies.html):\n\n    libraryDependencies += \"com.madewithtea\" %% \"mockedstreams\" % \"3.9.0\" % \"test\"\n\nJava 8 port of Mocked Streams is [Mockafka](https://github.com/carlosmenezes/mockafka)\n\n## Apache Kafka Compatibility\n\n| Mocked Streams Version        | Apache Kafka Version           |\n|------------- |-------------|\n| 3.9.0     | 2.7.0.0 |\n| 3.8.0     | 2.6.1.0 |\n| 3.7.0     | 2.5.0.0 |\n| 3.6.0      | 2.4.1.0 |\n| 3.5.2      | 2.4.0.0 |\n| 3.5.1      | 2.4.0.0 |\n| 3.5.0      | 2.4.0.0 |\n| 3.4.0      | 2.3.0.0 |\n| 3.3.0      | 2.2.0.0 |\n| 3.2.0      | 2.1.1.0 | \n| 3.1.0      | 2.1.0.0 | \n| 2.2.0      | 2.1.0.0 | \n| 2.1.0      | 2.0.0.0 | \n| 2.0.0      | 2.0.0.0 |\n| 1.8.0      | 1.1.1.0 |\n| 1.7.0      | 1.1.0.0 |\n| 1.6.0      | 1.0.1.0 |\n| 1.5.0      | 1.0.0.0 |\n| 1.4.0      | 0.11.0.1 | \n| 1.3.0      | 0.11.0.0 | \n| 1.2.1      | 0.10.2.1 | \n| 1.2.0      | 0.10.2.0 | \n| 1.1.0      | 0.10.1.1 | \n| 1.0.0      | 0.10.1.0 |    \n\n## Simple Example\n\nIt wraps the [org.apache.kafka.streams.TopologyTestDriver](https://github.com/apache/kafka/blob/trunk/streams/test-utils/src/main/java/org/apache/kafka/streams/TopologyTestDriver.java) class, but adds more syntactic sugar to keep your test code simple:\n\n    import com.madewithtea.mockedstreams.MockedStreams\n\n    val input = Seq((\"x\", \"v1\"), (\"y\", \"v2\"))\n    val exp = Seq((\"x\", \"V1\"), (\"y\", \"V2\"))\n    val strings = Serdes.String()\n\n    MockedStreams()\n      .topology { builder =\u003e builder.stream(...) [...] } // Scala DSL\n      .input(\"topic-in\", strings, strings, input)\n      .output(\"topic-out\", strings, strings) shouldEqual exp\n\n## Multiple Input / Output Example and State\n\nIt also allows you to have multiple input and output streams. If your topology uses state stores you need to define them using .stores(stores: Seq[String]):\n\n    import com.madewithtea.mockedstreams.MockedStreams\n\n    val mstreams = MockedStreams()\n      .topology { builder =\u003e builder.stream(...) [...] } // Scala DSL\n      .input(\"in-a\", strings, ints, inputA)\n      .input(\"in-b\", strings, ints, inputB)\n      .stores(Seq(\"store-name\"))\n\n    mstreams.output(\"out-a\", strings, ints) shouldEqual(expectedA)\n    mstreams.output(\"out-b\", strings, ints) shouldEqual(expectedB)\n\n## Record order and multiple emissions\n\nThe records provided to the mocked stream will be submitted to the topology during the test in the order in which they appear in the fixture. You can also submit records multiple times to the same topics, at various moments in your scenario. \n\nThis can be handy to validate that your topology behaviour is or is not dependent on the order in which the records are received and processed. \n\nIn the example below, 2 records are first submitted to topic A, then 3 to topic B, then 1 more to topic A again. \n\n    val firstInputForTopicA = Seq((\"x\", int(1)), (\"y\", int(2)))\n    val firstInputForTopicB = Seq((\"x\", int(4)), (\"y\", int(3)), (\"y\", int(5)))\n    val secondInputForTopicA = Seq((\"y\", int(4)))\n\n    val expectedOutput = Seq((\"x\", 5), (\"y\", 5), (\"y\", 7), (\"y\", 9))\n\n    val builder = MockedStreams()\n      .topology(topologyTables) // Scala DSL\n      .input(InputATopic, strings, ints, firstInputForTopicA)\n      .input(InputBTopic, strings, ints, firstInputForTopicB)\n      .input(InputATopic, strings, ints, secondInputForTopicA)\n\n## State Store \n\nWhen you define your state stores via .stores(stores: Seq[String]) since 1.2, you are able to verify the state store content via the .stateTable(name: String) method:  \n\n    import com.madewithtea.mockedstreams.MockedStreams\n\n     val mstreams = MockedStreams()\n      .topology { builder =\u003e builder.stream(...) [...] } // Scala DSL\n      .input(\"in-a\", strings, ints, inputA)\n      .input(\"in-b\", strings, ints, inputB)\n      .stores(Seq(\"store-name\"))\n\n     mstreams.stateTable(\"store-name\") shouldEqual Map('a' -\u003e 1) \n\n## Window State Store \n\nWhen you define your state stores via .stores(stores: Seq[String]) since 1.2 and added the timestamp extractor to the config, you are able to verify the window state store content via the .windowStateTable(name: String, key: K) method:  \n\n    import com.madewithtea.mockedstreams.MockedStreams\n\n    val props = new Properties\n    props.put(StreamsConfig.DEFAULT_TIMESTAMP_EXTRACTOR_CLASS_CONFIG,\n      classOf[TimestampExtractors.CustomTimestampExtractor].getName)\n\n    val mstreams = MockedStreams()\n      .topology { builder =\u003e builder.stream(...) [...] } // Scala DSL\n      .input(\"in-a\", strings, ints, inputA)\n      .stores(Seq(\"store-name\"))\n      .config(props)\n\n    mstreams.windowStateTable(\"store-name\", \"x\") shouldEqual someMapX\n    mstreams.windowStateTable(\"store-name\", \"y\") shouldEqual someMapY\n\n## Adding Timestamps\n\nWith .input the input records timestamps are set to 0 default timestamp of 0. This e.g. prevents testing Join windows of Kafka streams as it cannot produce records with different timestamps. However, using .inputWithTime allows adding timestamps like in the following example: \n\n    val inputA = Seq(\n      (\"x\", int(1), 1000L),\n      (\"x\", int(1), 1001L),\n      (\"x\", int(1), 1002L)\n    )\n\n    val builder = MockedStreams()\n      .topology(topology1WindowOutput) // Scala DSL\n      .inputWithTime(InputCTopic, strings, ints, inputA)\n      .stores(Seq(StoreName))\n\n\n## Custom Streams Configuration\n\nSometimes you need to pass a custom configuration to Kafka Streams:\n\n    import com.madewithtea.mockedstreams.MockedStreams\n\n      val props = new Properties\n      props.put(StreamsConfig.DEFAULT_TIMESTAMP_EXTRACTOR_CLASS_CONFIG, classOf[CustomExtractor].getName)\n\n      val mstreams = MockedStreams()\n      .topology { builder =\u003e builder.stream(...) [...] } // Scala DSL\n      .config(props)\n      .input(\"in-a\", strings, ints, inputA)\n      .input(\"in-b\", strings, ints, inputB)\n      .stores(Seq(\"store-name\"))\n\n    mstreams.output(\"out-a\", strings, ints) shouldEqual(expectedA)\n    mstreams.output(\"out-b\", strings, ints) shouldEqual(expectedB)\n \n## Companies using Mocked Streams \n\n* [BlaBlaCar](https://medium.com/blablacar-tech)\n* [PMU.fr](https://www.pmu.fr/)\n* [Sky.uk](https://www.sky.com/)\n* [Hive Streaming AB](https://www.hivestreaming.com/)\n* [moip, a wirecard company](https://moip.com.br/en/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpzk%2Fmockedstreams","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpzk%2Fmockedstreams","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpzk%2Fmockedstreams/lists"}