{"id":22750110,"url":"https://github.com/pwall567/kjson-spring-test","last_synced_at":"2026-05-08T19:33:31.813Z","repository":{"id":44990753,"uuid":"509324827","full_name":"pwall567/kjson-spring-test","owner":"pwall567","description":"Spring JSON testing functions for kjson","archived":false,"fork":false,"pushed_at":"2023-10-15T10:35:54.000Z","size":122,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-06T08:53:12.967Z","etag":null,"topics":["json","kotlin","spring","testing"],"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/pwall567.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,"publiccode":null,"codemeta":null}},"created_at":"2022-07-01T04:55:24.000Z","updated_at":"2023-07-18T09:14:04.000Z","dependencies_parsed_at":"2023-10-16T03:18:16.019Z","dependency_job_id":"d1a78a14-9e6f-4eed-a62a-addff71ae7e5","html_url":"https://github.com/pwall567/kjson-spring-test","commit_stats":{"total_commits":6,"total_committers":1,"mean_commits":6.0,"dds":0.0,"last_synced_commit":"54ed6f55672f647d1d123c77fd1ca612e4665623"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/pwall567/kjson-spring-test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-spring-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-spring-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-spring-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-spring-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pwall567","download_url":"https://codeload.github.com/pwall567/kjson-spring-test/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson-spring-test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32794715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"ssl_error","status_checked_at":"2026-05-08T08:22:45.650Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["json","kotlin","spring","testing"],"created_at":"2024-12-11T04:12:25.714Z","updated_at":"2026-05-08T19:33:31.795Z","avatar_url":"https://github.com/pwall567.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kjson-spring-test\n\n[![Build Status](https://travis-ci.com/pwall567/kjson-spring-test.svg?branch=main)](https://travis-ci.com/github/pwall567/kjson-spring-test)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Kotlin](https://img.shields.io/static/v1?label=Kotlin\u0026message=v1.8.22\u0026color=7f52ff\u0026logo=kotlin\u0026logoColor=7f52ff)](https://github.com/JetBrains/kotlin/releases/tag/v1.8.22)\n[![Maven Central](https://img.shields.io/maven-central/v/io.kjson/kjson-spring-test?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.kjson%22%20AND%20a:%22kjson-spring-test%22)\n\nSpring JSON testing functions for [`kjson`](https://github.com/pwall567/kjson).\n\n## **IMPORTANT**\n\n**Version 4.4 is a major re-work of this library, and it will be a breaking change for users of earlier versions.**\n\nPrior to version 4.4, the library used a flawed technique for acquiring the `JSONConfig` used by the application.\nSometimes it would work, but many times it wouldn\u0026rsquo;t.\n\n**Version 4.4.3 is a further revision of these changes**; the `JSONMockMvc` class introduced with the earlier changes\nhas been dropped in favour of a set of extension functions on `MockMvc`.\n\n## Background\n\nThe [Spring Framework](https://spring.io/projects/spring-framework) provides a number of classes to assist with testing;\nthe `kjson-spring-test` library adds functionality to simplify the use of these tests in conjunction with the\n[`kjson`](https://github.com/pwall567/kjson) library.\n\n## Incoming Requests and `MockMvc`\n\nThe testing of incoming REST requests involves setting up incoming calls, and then testing the result to confirm that\nit matches the expected status, data _etc._\n\nThe `kjson-spring-test` library can help with both of these aspects of incoming request testing, including the use of\nthe `kjson-test` library for testing / matching the response.\n\n### `getForJSON`, `postForJSON`\n\nThe Kotlin extensions for Spring added `get`, `post` functions _etc._ to `MockMvc`, each function taking a lambda using\na DSL to configure the operation.\nThe `kjson-spring-test` library adds `getForJSON`, `putForJSON`, `postForJSON` and `deleteForJSON`, which set the\n`Accept` header to `application/json` to indicate that the expected response is JSON, along with `putJSON` and\n`postJSON` which do not set the `Accept` header but still allow JSON request content.\n\nFor example:\n```kotlin\n        mockMvc.getForJSON(\"/testendpoint\") {\n            header(\"X-Custom-Header\", \"value\")\n        }.andExpect {\n            // check response\n        }\n```\n\nThe functions use a DSL broadly similar to that used by the existing `get` and `post` functions, as shown in the example\nabove, which uses the `header` function from that DSL.\nA major difference is in the handling of the `content` property of the DSL \u0026ndash; if it is set to a `String` or\n`ByteArray` value it will be used as is, but any other type of object will be serialized using the `kjson` library, and\nJSON form will be sent as the content (with the `Content-Type` set to `application/json`, unless already set to a\ndifferent value).\n\n### `contentJSON`\n\nTo set the JSON content explicitly as JSON, the `contentJSON` function may be used:\n```kotlin\n        mockMvc.postForJSON(\"/testendpoint\") {\n            contentJSON {\n                RequestData(\n                    id = customerId,\n                    name = customerName,\n                )\n            }\n        }.andExpect {\n            // check response\n        }\n```\nThere are two forms of the function, one which takes an object to be serialised and another (shown above) that takes a\nlambda which will be invoked to create the object.\n\nThe `kjson` serialization will use the autowired `JSONConfig` configuration as described [below](#configuration).\n\n### `matchesJSON`, `contentMatchesJSON`\n\nThe results of the `MockMvc` extension functions may be tested using the\n[`kjson-test`](https://github.com/pwall567/kjson-test) library.\n\nThe Spring Kotlin extensions include the `content` function, which allows the specification of tests against the content\nof the result.\n`kjson-spring-test` adds the `matchesJSON` function within the content DSL;\nthis function parses the result as JSON, and then executes the `kjson-test` test specifications against the parsed\nresult.\nFor example:\n```kotlin\n        mockMvc.getForJSON(\"/testendpoint\") {\n            header(\"X-Custom-Header\", \"value\")\n        }.andExpect {\n            status { isOk() }\n            content {\n                matchesJSON {\n                    property(\"date\", LocalDate.of(2022, 7, 6))\n                    property(\"extra\", \"ResultValue\")\n                }\n            }\n        }\n```\n\nAlternatively, if the only function inside `content` is `matchesJSON`, the two may be combined:\n```kotlin\n        mockMvc.getForJSON(\"/testendpoint\") {\n            header(\"X-Custom-Header\", \"value\")\n        }.andExpect {\n            status { isOk() }\n            contentMatchesJSON {\n                property(\"date\", LocalDate.of(2022, 7, 6))\n                property(\"extra\", \"ResultValue\")\n            }\n        }\n```\n\nSee the documentation for [`kjson-test`](https://github.com/pwall567/kjson-test) for more details on the matching\ncapabilities available using that library.\n\n## Outgoing Requests and `JSONMockServer`\n\nThe testing of outgoing client REST requests is in some ways the reverse of incoming request testing.\nThe mock server is configured to match one or more possible requests, and to respond with the appropriate data.\n\nWhere the input request testing allows the use of the `kjson-test` library to test the result data, client request\ntesting allows the use of the same library for matching the requests (if complex matching is required).\n\nIn order to have access to the `kjson` serialization and deserialization functions, `kjson-spring-test` uses a wrapper\nclass around `MockRestServiceServer` named `JSONMockServer`.\n\n### Creating a `JSONMockServer`\n\nInstead of a Java static function, as in the case of `MockRestServiceServer`, the `JSONMockServer` must be obtained from\nthe `JSONSpringTest` service, as follows:\n```kotlin\n    @Autowired lateinit var jsonSpringTest: JSONSpringTest\n```\nThen, in the code (either in the test function or in a `@BeforeTest` function):\n```kotlin\n        val mockServer = jsonSpringTest.createServer(restTemplate)\n```\n\n### `mock`, `mockGet`, `mockPost`\n\n`MockRestServiceServer` provides facilities for testing REST clients, but the conventional use of this class involves a\nchain of \"fluent\" function calls, using `MockRestRequestMatchers` static functions.\n`JSONMockServer` provides a DSL-based approach to client testing.\n\nThe `mock` function allows mock requests to be declared in a Kotlin idiomatic\nmanner:\n```kotlin\n    mockServer.mock {\n        requestTo(\"/endpoint\")\n        method(HttpMethod.GET)\n        header(\"X-Custom-Header\", \"value\")\n    }\n```\n\nThe parameters for the `mock` function are:\n\n| Name            | Type            | Default                | Description                                               |\n|-----------------|-----------------|------------------------|-----------------------------------------------------------|\n| `expectedCount` | `ExpectedCount` | `ExpectedCount.once()` | The number of times the request is expected to be invoked |\n| `method`        | `HttpMethod`    | `HttpMethod.GET`       | The expected method                                       |\n| `uri`           | `URI`           | none                   | The expected URI                                          |\n| `block`         | lambda          | none                   | The DSL lambda (see below)                                |\n\nThere are also `mockGet`, `mockPut`, `mockPost` and `mockDelete` functions; these are convenience functions that avoid\nthe need to specify the method separately (although as noted above, `GET` is the default).\nThey do not take a `method` parameter (obviously).\n\nMany of the functions within the `mock` lambda are named identically to the `MockRestRequestMatchers` static functions,\nbut in this case they are functions in the DSL created by the `mock` function.\nThere are also additional functions related to the use of JSON.\n\nThe following functions are available:\n\n| Name                         | Parameter(s)                               | Description                                                             |\n|------------------------------|--------------------------------------------|-------------------------------------------------------------------------|\n| `requestTo`                  | `String`                                   | Matches the URI by string                                               |\n| `requestTo`                  | `URI`                                      | Matches the URI                                                         |\n| `requestTo`                  | `(String) -\u003e Boolean`                      | Matches the URI using a lambda                                          |\n| `requestTo`                  | `Matcher\u003cString\u003e`                          | Matches the URI using a `Matcher`                                       |\n| `method`                     | `HttpMethod`                               | Matches the method                                                      |\n| `queryParam`                 | `String`, `vararg String`                  | Matches a named query parameter against a set of values                 |\n| `header`                     | `String`, `vararg String`                  | Matches a named header against a set of values                          |\n| `header`                     | `String`, `(String) -\u003e Boolean`            | Matches a named header using a lambda                                   |\n| `header`                     | `String`, `vararg Matcher\u003cString\u003e`         | Matches a named header against a set of values using `Matcher`s         |\n| `accept`                     | `MediaType`                                | Matches the `Accept` header with the specified `MediaType`              |\n| `acceptApplicationJSON`      |                                            | Matches the `Accept` header as compatible with `application/json`       |\n| `contentType`                | `MediaType`                                | Matches the `Content-Type` header with the specified `MediaType`        |\n| `contentTypeApplicationJSON` |                                            | Matches the `Content-Type` header as compatible with `application/json` |\n| `headerDoesNotExist`         | `String`                                   | Expects the named header to not be present                              |\n| `requestContent`             | `String`                                   | Matches the request body against a `String`                             |\n| `requestContent`             | `(String) -\u003e Boolean`                      | Matches the request body using a lambda                                 |\n| `requestJSON`                | lambda - see below                         | Matches the request body using the `kjson-test` library                 |\n| `respond`                    | `HttpStatus`, `HttpHeaders?`, `String`     | Supplies the status, headers and a result string to send as a response  |\n| `respondJSON`                | `HttpStatus`, `HttpHeaders?`, `Any?`       | As above, but the result object is converted to JSON for output         |\n| `respondJSON`                | `HttpStatus`, `HttpHeaders?`, `() -\u003e Any?` | As above, but the lambda is called to create the result object          |\n\nThe `requestJSON` function allows the request body to be matched using the\n[`kjson-test`](https://github.com/pwall567/kjson-test) library.\nFor example:\n```kotlin\n    mockServer.mock {\n        requestTo(\"/endpoint\")\n        method(HttpMethod.POST)\n        requestJSON {\n            property(\"id\", isUUID)\n            property(\"name\", length(1..99))\n        }\n    }\n```\nSee the documentation for [`kjson-test`](https://github.com/pwall567/kjson-test) for more details on the matching\ncapabilities available using that library.\n\nThe `respond` and `respondJSON` functions allow the specification of the mock response.\nIn the case of `respond`, the result may be supplied as a `String`, or may be omitted, as might be appropriate for\nstatus code 204 (No Content).\n```kotlin\n    mockServer.mock {\n        requestTo(\"/endpoint\")\n        method(HttpMethod.GET)\n        respond(HttpStatus.NO_CONTENT)\n    }\n```\n\nThe full set of parameters for `respond` is:\n\n| Name      | Type          | Default          | Description                                       |\n|-----------|---------------|------------------|---------------------------------------------------|\n| `status`  | `HttpStatus`  | `HttpStatus.GET` | The status to be returned                         |\n| `headers` | `HttpHeaders` | empty list       | The headers to be added to the response           |\n| `result`  | `String?`     | `null`           | The result as a `String` (`null` means no result) |\n\nThe `respondJSON` function allows the specification of a result object that will be serialised to JSON, and in the case\nof the form that takes a lambda parameter, the `JSONMockClientRequest` describing the request will be supplied as the\nreceiver object, allowing the use of data from the request in the creation of the response:\n```kotlin\n    mockServer.mock {\n        requestTo { it.startsWith(\"/testendpoint/\") }\n        method(HttpMethod.GET)\n        respondJSON {\n            ResponseData(LocalDate.now(), uri.path.substringAfterLast('/'))\n        }\n    }\n```\n\nThe `kjson` serialization will use the `JSONConfig` configuration as described [below](#configuration), and that\n`JSONConfig` is available within the lambda as the `config` property of the `JSONMockClientRequest`.\n\nThe full set of parameters for `respondJSON` is:\n\n| Name      | Type          | Default          | Description                              |\n|-----------|---------------|------------------|------------------------------------------|\n| `status`  | `HttpStatus`  | `HttpStatus.GET` | The status to be returned                |\n| `headers` | `HttpHeaders` | empty list       | The headers to be added to the response  |\n| `block`   | lambda        | none             | The lambda to create the response object |\n\n### `JSONResponseActions.respondJSON`\n\nAs an alternative to the use of the `respondJSON` function within the request configuration block, the library also\nprovides a `respondJSON` function in the `JSONResponseActions` returned by the `mock` functions, and this may be chained\nonto those functions.\nThis form of the `respondJSON` function takes the same parameters as the one described above, but it differs in that the\nlambda that creates the response object does not have access to the `JSONMockClientRequest`.\n\nTo configure the mock operation to respond with a JSON object:\n```kotlin\n    mockServer.mockGet {\n        requestTo(\"/endpoint\")\n    }.respondJSON {\n        ResponseData(date = LocalDate.now(), extra = \"XYZ\")\n    }\n```\n\n### `verify`\n\nThe `verify` functions of `MockRestServiceServer` are also available in `JSONMockServer`:\n```kotlin\n        mockServer.verify()\n```\n\n## Configuration\n\nThe `kjson` serialization and deserialization functions all take an optional\n[`JSONConfig`](https://github.com/pwall567/kjson/blob/main/USERGUIDE.md#configuration) object.\nThe `JSONConfig` to be used by the functions invoked by the `kjson-spring-test` library may be provided in the usual\nSpring manner:\n```kotlin\n@Configuration\nopen class SpringAppConfig {\n\n    @Bean open fun config(): JSONConfig {\n        return JSONConfig {\n            // configuration options here\n        }\n    }\n\n}\n```\n\nIf the project is also using the [`kjson-spring`](https://github.com/pwall567/kjson-spring) library, the same\nconfiguration may be shared by both libraries.\n\n## Dependency Specification\n\nThe latest version of the library is 7.1 (the version number of this library matches the version of `kjson` with which\nit was built), and it may be obtained from the Maven Central repository.\n(The following dependency declarations assume that the library will be included for test purposes; this is\nexpected to be its principal use.)\n\nThis version was built using version 5.3.30 of Spring, and version 2.7.16 of Spring Boot.\n\n### Maven\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003eio.kjson\u003c/groupId\u003e\n      \u003cartifactId\u003ekjson-spring-test\u003c/artifactId\u003e\n      \u003cversion\u003e7.1\u003c/version\u003e\n      \u003cscope\u003etest\u003c/scope\u003e\n    \u003c/dependency\u003e\n```\n### Gradle\n```groovy\n    testImplementation 'io.kjson:kjson-spring-test:7.1'\n```\n### Gradle (kts)\n```kotlin\n    testImplementation(\"io.kjson:kjson-spring-test:7.1\")\n```\n\nPeter Wall\n\n2023-10-15\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fkjson-spring-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpwall567%2Fkjson-spring-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fkjson-spring-test/lists"}