{"id":21388173,"url":"https://github.com/droidsonroids/mockwebserver-path-dispatcher","last_synced_at":"2025-07-13T15:32:19.876Z","repository":{"id":46537609,"uuid":"94370662","full_name":"DroidsOnRoids/mockwebserver-path-dispatcher","owner":"DroidsOnRoids","description":"A helper for dispatching MockWebServer responses","archived":false,"fork":false,"pushed_at":"2023-08-02T01:06:00.000Z","size":1272,"stargazers_count":10,"open_issues_count":0,"forks_count":10,"subscribers_count":5,"default_branch":"develop","last_synced_at":"2024-03-27T00:13:58.555Z","etag":null,"topics":["hacktoberfest","http","mock","mock-server","mockwebserver","querystrings","testing","url"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/DroidsOnRoids.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":"2017-06-14T20:31:36.000Z","updated_at":"2024-03-27T00:13:58.556Z","dependencies_parsed_at":"2023-02-08T16:31:49.408Z","dependency_job_id":null,"html_url":"https://github.com/DroidsOnRoids/mockwebserver-path-dispatcher","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DroidsOnRoids%2Fmockwebserver-path-dispatcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DroidsOnRoids%2Fmockwebserver-path-dispatcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DroidsOnRoids%2Fmockwebserver-path-dispatcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DroidsOnRoids%2Fmockwebserver-path-dispatcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DroidsOnRoids","download_url":"https://codeload.github.com/DroidsOnRoids/mockwebserver-path-dispatcher/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225893696,"owners_count":17540918,"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":["hacktoberfest","http","mock","mock-server","mockwebserver","querystrings","testing","url"],"created_at":"2024-11-22T12:16:09.088Z","updated_at":"2025-07-13T15:32:19.870Z","avatar_url":"https://github.com/DroidsOnRoids.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Javadocs](https://javadoc.io/badge/pl.droidsonroids.testing/mockwebserver-path-dispatcher.svg?color=blue)](https://javadoc.io/doc/pl.droidsonroids.testing/mockwebserver-path-dispatcher)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/pl.droidsonroids.testing/mockwebserver-path-dispatcher/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/pl.droidsonroids.testing/mockwebserver-path-dispatcher)\n\nMockWebServer path dispatcher\n=============\n\nA helper for dispatching MockWebServer responses. It allows to easily mock responses with data\nstored in YAML files in `resources/fixtures/` directory\n\n### Motivation\n\n- YAML used to store responses for more readability (compared to\n  bare [MockWebServer](https://github.com/square/okhttp/tree/master/mockwebserver))\n- Android compatible (unlike [MockWebServer+](https://github.com/orhanobut/mockwebserverplus))\n- Concise dispatching logic implementation\n\n### Example\n\nCode with MockWebServer path dispatcher:\n\n```kotlin\nfun pathCondition() {\n    val dispatcher = FixtureDispatcher()\n    // match all URLs with path starting with /prefix/ e.g. http://example.test/prefix/\n    val factory = PathQueryConditionFactory(\"/prefix/\")\n    // match all URLs with path ending with \"suffix\" and return response from fixtures/body_text_path.yaml\n    dispatcher.putResponse(factory.withPathSuffix(\"suffix\"), \"body_text_path\")\n    dispatcher.putResponse(factory.withPathSuffix(\"another_suffix\"), \"json_object\")\n    mockWebServer.setDispatcher(dispatcher)\n}\n```\n\nExample YAML file at `resources/fixtures/json_object.yaml`:\n\n```yaml\nstatusCode : 200\nheaders:\n- 'Content-Type: application/json'\nbody: \u003e\n    {\n      \"test\": null\n    }\n```\n\nInstead of defining body in yaml directly you can specify relative path to file with body.\nThere are 3 different types of files supported: json, text, and binary.\n\n### JSON\n\nBy default the file is read as a JSON file. Id you don't specify the `Content-Type` it defaults to \n`application/json` and creates a `BodyContent.Json`:\n\n```yaml\nstatusCode : 404\nheaders:\n- \"Vary: Accept-Encoding\"\nbody: body_json.txt\n```\n### Plain text\n\nTo create plain text responses, set the `Content-Type` to `text/plain`. The body will be an instance\nof `BodyContent.Text`:\n\n```yaml\nstatusCode : 404\nheaders:\n- 'Content-Type: text/plain'\n- \"Vary: Accept-Encoding\"\nbody: body.txt\n```\n\n### Binary\n\nTo create binary responses, set the `Content-Type` to anythin different than `application-json` or \n`text/plain`. The body will be an instance of `BodyContent.Binary`:\n\n```yaml\nstatusCode : 404\nheaders:\n- 'Content-Type: image/jpeg'\n- \"Vary: Accept-Encoding\"\nbody: image.jpeg\n```\n\n### Connection issues simulation\n\nYou can force the request to fail by setting `connectionFailure` to `true`:\n\n```yaml\nstatusCode : 200\nconnectionFailure: true\n```\n\nAlternatively, you can specify not getting a response by simulating a timeout with `timeoutFailure` to `true`:\n\n```yaml\nstatusCode : 200\ntimeoutFailure: true\n```\n\n### MockWebServer without this library\n\nCode without MockWebServer path dispatcher:\n\n```kotlin\nfun bareMockWebServer() {\n    val dispatcher = object : Dispatcher() {\n        override fun dispatch(request: RecordedRequest): MockResponse {\n            val path = request.requestUrl.encodedPath()\n            if (path == \"/prefix/suffix\") {\n                return MockResponse()\n                        .setResponseCode(404)\n                        .addHeader(\"Content-Type\", \"text/plain\")\n                        .addHeader(\"Vary\", \"Accept-Encoding\")\n                        .setBody(\"\"\"{\"test\"}\"\"\")\n            } else if (path == \"/prefix/another_suffix\") {\n                return MockResponse()\n                        .setResponseCode(200)\n                        .addHeader(\"Content-Type\", \"application/json\")\n                        .setBody(\"{\\n  \\\"test\\\": null\\n}\")\n            }\n            throw IllegalArgumentException(\"Unexpected request: $request\")\n        }\n    }\n    mockWebServer.setDispatcher(dispatcher)\n}\n```\n\nSee more examples\nat [FunctionalTest.kt](dispatcher/src/test/kotlin/pl/droidsonroids/testing/mockwebserver/FunctionalTest.kt)\n\n### API\n\n`FixtureDispatcher` - when you want conditional fixture response mapping and enqueuing:\n\n```kotlin\nfun factory() {\n    val dispatcher = FixtureDispatcher()\n    val factory = PathQueryConditionFactory(\"/prefix/\")\n    // bar will be served for first matching requests\n    dispatcher.enqueue(factory.withPathSuffix(\"suffix\"), \"bar\")\n    // bar will be served for second matching requests\n    dispatcher.enqueue(factory.withPathSuffix(\"suffix\"), \"baz\")\n    // foo will be served by default (if there is nothing enqueued) for subsequent matching requests\n    dispatcher.putResponse(factory.withPathSuffix(\"suffix\"), \"foo\")    \n    // qux will be served by default when there are no matching requests\n    dispatcher.setFallbackResponse(\"qux\")    \n    mockWebServer.setDispatcher(dispatcher)\n}\n```\n\n`PathQueryConditionFactory` - when you want to use common URL path prefix multiple times:\n\n```kotlin\nfun factory() {\n    val dispatcher = FixtureDispatcher()\n    val factory = PathQueryConditionFactory(\"/prefix/\")\n    dispatcher.putResponse(factory.withPathSuffix(\"suffix\"), \"queryless_response\")\n    // match all URLs with path ending with \"suffix\" and have \"param\" with any value as query parameter e.g. http://example.test/prefix/user/suffix?param\n    dispatcher.putResponse(factory.withPathSuffixAndQueryParameter(\"suffix\", \"param\"), \"response_with_query_parameter\")\n    // match all URLs with path ending with \"suffix\" and have \"param\" with \"value\" as query parameter e.g. http://example.test/prefix/user/suffix?param=value\n    dispatcher.putResponse(factory.withPathSuffixAndQueryParameter(\"suffix\", \"param\", \"value\"), \"response_with_query_parameter_and_value\")\n    // match all URLs with path ending with \"suffix\" and have multiple parameter name/value pairs e.g.http://example.test/prefix/user/suffix?param=value\u0026param2=value2\n    dispatcher.putResponse(\n        factory.withPathSuffixAndQueryParameters(\"suffix\", mapOf(\"param\" to \"value\", \"param2\" to \"value2\")),\n        \"response_with_multiple_query_parameters\"\n    )\n    mockWebServer.setDispatcher(dispatcher)\n}\n```\n\n`PathQueryCondition` - when you want to match by path and optional query parameter:\n\n```kotlin\nfun pathQueryCondition() {\n    val dispatcher = FixtureDispatcher()\n    dispatcher.putResponse(PathQueryCondition(\"/prefix/suffix\", \"param\", \"value\"), \"response_with_query_parameter_and_value\")\n    mockWebServer.setDispatcher(dispatcher)\n    \n}\n```\nAlso supports a map of multiple query parameters:\n\n```kotlin\nfun pathQueryConditions() {\n    val dispatcher = FixtureDispatcher()\n    dispatcher.putResponse(PathQueryCondition(\"/prefix/suffix\", mapOf(\"param\" to \"value\", \"param2\" to \"value2\")), \"response_with_query_parameters_and_values\")\n    mockWebServer.setDispatcher(dispatcher)\n}\n```\n\n`HttpUrlCondition` - when you want to match by some part of URL other than path or single query\nparameter:\n\n```kotlin\nfun httpUrlCondition() {\n    val dispatcher = FixtureDispatcher()\n    val condition = object : HttpUrlCondition() {\n        override fun isUrlMatching(url: HttpUrl) = url.encodedUsername() == \"foo\"\n\n        override fun compareTo(other: Condition) = 0\n    }\n    dispatcher.putResponse(condition , \"response_for_foo\")\n    mockWebServer.setDispatcher(dispatcher)    \n}\n```\n\n`Condition` - when you want to match by non-URL parts of the request e.g. headers:\n\n```kotlin\nfun condition() {\n    val condition = object : Condition {\n        override fun isRequestMatching(request: RecordedRequest)= request.getHeader(\"Content-Type\") == \"application/json\"\n\n        override fun compareTo(other: Condition) = 0\n    }\n    dispatcher.putResponse(condition , \"json_response\")   \n}\n```\n\n`BodyContentTransformer` - when you want to modify the response before being returned to the user \nyou can create a transformer and set it to the dispatcher. The transformer is very useful when you \nwant to replace some urls (i.e. images) to your mock server url so they go through the dispatcher \nand you can then be able to mock the responses and load fake image or files:\n\n```kotlin\nfun transformResponseUrls() {\n    val mockServerUrl = … // Get the url from your MockWebServer\n    dispatcher.setBodyContentTransformerResponse{ bodyContent -\u003e\n      if (bodyContent is BodyContent.Json) {\n        bodyContent.copy(\n          bodyContent.content.replace(\"https://my.domain/\", mockServerUrl)\n        )\n      } else {\n        bodyContent\n      }\n    }   \n}\n```\n\n### Download\n\nFor unit tests:\n\n```gradle\ntestImplementation 'pl.droidsonroids.testing:mockwebserver-path-dispatcher:1.2.0'\n```\n\nor for Android instrumentation tests:\n\n```gradle\nandroidTestImplementation 'pl.droidsonroids.testing:mockwebserver-path-dispatcher:1.2.0'\n```\n\n### License\n\nLibrary uses the MIT License. See [LICENSE](LICENSE) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdroidsonroids%2Fmockwebserver-path-dispatcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdroidsonroids%2Fmockwebserver-path-dispatcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdroidsonroids%2Fmockwebserver-path-dispatcher/lists"}