{"id":15481565,"url":"https://github.com/dius/pact-consumer-swift","last_synced_at":"2025-07-11T03:07:06.202Z","repository":{"id":25790708,"uuid":"29229243","full_name":"DiUS/pact-consumer-swift","owner":"DiUS","description":"A Swift / ObjeciveC DSL for creating pacts.","archived":false,"fork":false,"pushed_at":"2021-09-06T06:36:48.000Z","size":31793,"stargazers_count":99,"open_issues_count":9,"forks_count":43,"subscribers_count":59,"default_branch":"master","last_synced_at":"2025-06-25T00:26:39.445Z","etag":null,"topics":["contract-testing","hacktoberfest","objective-c","pact","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/DiUS.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-14T05:41:05.000Z","updated_at":"2025-05-04T06:15:23.000Z","dependencies_parsed_at":"2022-08-24T14:14:34.815Z","dependency_job_id":null,"html_url":"https://github.com/DiUS/pact-consumer-swift","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/DiUS/pact-consumer-swift","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiUS%2Fpact-consumer-swift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiUS%2Fpact-consumer-swift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiUS%2Fpact-consumer-swift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiUS%2Fpact-consumer-swift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DiUS","download_url":"https://codeload.github.com/DiUS/pact-consumer-swift/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DiUS%2Fpact-consumer-swift/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264719240,"owners_count":23653542,"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":["contract-testing","hacktoberfest","objective-c","pact","swift"],"created_at":"2024-10-02T05:04:56.193Z","updated_at":"2025-07-11T03:07:06.171Z","avatar_url":"https://github.com/DiUS.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pact Consumer Swift\n\n[![Build](https://github.com/DiUS/pact-consumer-swift/workflows/Build/badge.svg)](https://github.com/DiUS/pact-consumer-swift/actions?query=workflow%3ABuild)\n[![Codecov](https://codecov.io/gh/DiUS/pact-consumer-swift/branch/master/graph/badge.svg)](https://codecov.io/gh/DiUS/pact-consumer-swift)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-brightgreen.svg)][swift-package-manager]\n[![Swift](https://img.shields.io/badge/Swift-5-orange.svg?style=flat)](https://swift.org/)\n[![Badge w/ CocoaPod Version](https://cocoapod-badges.herokuapp.com/v/PactConsumerSwift/badge.png)](https://cocoadocs.org/docsets/PactConsumerSwift)\n[![Badge w/ Supported Platforms](https://cocoapod-badges.herokuapp.com/p/PactConsumerSwift/badge.svg)](https://cocoadocs.org/docsets/PactConsumerSwift)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Twitter](https://img.shields.io/badge/twitter-@pact__up-blue.svg?style=flat)](http://twitter.com/pact_up)\n\n\u003e ℹ  \n\u003e A new version featuring [Pact Specification v3][pact-spec-v3], a simplified installation and better management of the mock server processes is in active development and can be found at [PactSwift][pact-swift]. We are currently looking for people to try it out and provide feedback.\n\nThis library provides a Swift / Objective C DSL for creating Consumer [Pacts](http://pact.io). It provides support for **[Consumer Driven Contract Testing][pact-microservices]** between dependent systems where the integration is based on HTTP (or message queues for some of the implementations).\n\n_But why?_ To test communication boundaries between your app and services.\nYou can view a presentation on how Pact can work in a mobile context here: [Yow! Connected 2016 Andrew Spinks - Increasing The Confidence In Your Service Integrations](https://www.youtube.com/watch?v=UQkMr4bKYp4).\n\nImplements [Pact Specification v2][pact-spec-v2],\nincluding [flexible matching][pact-flexible-matching].\n\nThis DSL relies on the Ruby [pact-ruby-standalone][pact-ruby-standalone] ([brew tap][pact-ruby-standalone-homebrew]) to provide the mock service for the tests.\n\n## Installation\n\nNote: see [Upgrading][upgrading] for notes on upgrading from 0.2 to 0.3\n\n### Install Pact Mock Service\n\n#### Homebrew\n\n    brew tap pact-foundation/pact-ruby-standalone\n    brew install pact-ruby-standalone\n\nThis will install the following tools:\n\n    pact\n    pact-broker\n    pact-message\n    pact-mock-service\n    pact-provider-verifier\n    pact-publish\n    pact-stub-service\n\n#### Manually\n\nAlternatively you can download and install the [pact-ruby-standalone][pact-ruby-standalone] archives for your platform and install as per installation instructions written in [Pact Ruby Standalone release notes][pact-ruby-standalone-releases].\n\n#### Xcode Setup\n\nIn Xcode, edit your scheme and add _pre-_ and _post-actions_ to `Test` to start and stop `pact-mock-service`. Make sure you select your target in _Provide build settings from_ the drop down menu.\n\n```\n# Pre-actions\nPATH=/path/to/your/standalone/pact/bin:$PATH\npact-mock-service start --pact-specification-version 2.0.0 --log \"${SRCROOT}/tmp/pact.log\" --pact-dir \"${SRCROOT}/tmp/pacts\" -p 1234\n\n# Post-actions\nPATH=/path/to/your/standalone/pact/bin:$PATH\npact-mock-service stop\n```\nNote: your generated Pact files will be dropped into `\"${SRCROOT}/tmp/pacts\"` folder.\n\n![Xcode Scheme Test Pre-actions](scripts/images/xcode-scheme-test-pre-actions.png)\n\n### Add the PactConsumerSwift library to your project\n\n#### Using [Carthage](https://github.com/Carthage/Carthage)\n\n- See the [PactSwiftExample][pact-carthage-ios-example] [![Swift, Carthage Example - Build Status](https://travis-ci.org/andrewspinks/PactSwiftExample.svg?branch=master)][build-carthage-ios-example] for an example project using `pact-consumer-swift` with Carthage for an iOS target.\n- See the [PactMacOSExample][pact-carthage-macos-example] [![Build](https://github.com/surpher/PactMacOSExample/workflows/Build/badge.svg)][build-carthage-macos-example] for an example project using `pact-consumer-swift` through Carthage for a macOS target.\n\n#### Using [CocoaPods](https://cocoapods.org/pods/PactConsumerSwift)\n\n- See the [PactObjectiveCExample][pact-objc-example] [![Build Status](https://travis-ci.org/andrewspinks/PactObjectiveCExample.svg?branch=master)][build-objc-example] for an example project using `pact-consumer-swift` with CocoaPods for an iOS target.\n\n#### Using [Swift Package Manager][swift-package-manager]\n\n- See the [PactSwiftPMExample][pact-swiftpm-example] [![Build](https://github.com/surpher/PactSwiftPMExample/workflows/Build/badge.svg)][build-swiftpm-example] for an example project using `pact-consumer-swift` library through Swift Package Manager for an executable that runs in terminal.\n\n## Writing Pact Tests\n\n### Testing with Swift\n\n  Write a Unit test similar to the following (NB: this example is using the [Quick](https://github.com/Quick/Quick) test framework)\n\n```swift\nimport PactConsumerSwift\n\n...\n  beforeEach {\n    animalMockService = MockService(provider: \"Animal Service\", consumer: \"Animal Consumer Swift\")\n    animalServiceClient = AnimalServiceClient(baseUrl: animalMockService!.baseUrl)\n  }\n\n  it(\"gets an alligator\") {\n    animalMockService!.given(\"an alligator exists\")\n                      .uponReceiving(\"a request for an alligator\")\n                      .withRequest(method:.GET, path: \"/alligator\")\n                      .willRespondWith(status:200,\n                                       headers: [\"Content-Type\": \"application/json\"],\n                                       body: [\"name\": \"Mary\"])\n\n    //Run the tests\n    animalMockService!.run { (testComplete) -\u003e Void in\n      animalServiceClient!.getAlligator { (alligator) in\n        expect(alligator.name).to(equal(\"Mary\"))\n        testComplete()\n      }\n    }\n  }\n```\n\n  An optional `timeout` (seconds) parameter can be included on the run function. This defaults to 30 seconds.\n\n```swift\n...\n    animalMockService!.run(timeout: 60) { (testComplete) -\u003e Void in\n      animalServiceClient!.getAlligator { (alligator) in\n        expect(alligator.name).to(equal(\"Mary\"))\n        testComplete()\n      }\n    }\n```\n\n### Testing with Objective-C\n\n  Write a Unit test similar to the following\n\n```objc\n@import PactConsumerSwift;\n...\n- (void)setUp {\n  [super setUp];\n  self.animalMockService = [[MockService alloc] initWithProvider:@\"Animal Provider\"\n                                                        consumer:@\"Animal Service Client Objective-C\"];\n  self.animalServiceClient = [[OCAnimalServiceClient alloc] initWithBaseUrl:self.animalMockService.baseUrl];\n}\n\n- (void)testGetAlligator {\n  typedef void (^CompleteBlock)();\n\n  [[[[self.animalMockService given:@\"an alligator exists\"]\n                             uponReceiving:@\"oc a request for an alligator\"]\n                             withRequestHTTPMethod:PactHTTPMethodGET\n                                              path:@\"/alligator\"\n                                             query:nil headers:nil body:nil]\n                             willRespondWithHTTPStatus:200\n                                               headers:@{@\"Content-Type\": @\"application/json\"}\n                                                  body: @\"{ \\\"name\\\": \\\"Mary\\\"}\" ];\n\n  [self.animalMockService run:^(CompleteBlock testComplete) {\n      Animal *animal = [self.animalServiceClient getAlligator];\n      XCTAssertEqualObjects(animal.name, @\"Mary\");\n      testComplete();\n  }];\n}\n```\n\n  An optional `timeout` (seconds) parameter can be included on the run function. This defaults to 30 seconds.\n\n```objc\n...\n  [self.animalMockService run:^(CompleteBlock testComplete) {\n      Animal *animal = [self.animalServiceClient getAlligator];\n      XCTAssertEqualObjects(animal.name, @\"Mary\");\n      testComplete();\n  } timeout:60];\n}\n```\n\n### Testing with XCTest\n\nWrite a Unit Test similar to the following:\n\n```swift\nimport PactConsumerSwift\n...\n  var animalMockService: MockService?\n  var animalServiceClient: AnimalServiceClient?\n\n  override func setUp() {\n    super.setUp()\n\n    animalMockService = MockService(provider: \"Animal Provider\", consumer: \"Animal Service Client\")\n    animalServiceClient = AnimalServiceClient(baseUrl: animalMockService!.baseUrl)\n  }\n\n  func testItGetsAlligator() {\n    // Prepare the expecated behaviour using pact's MockService\n    animalMockService!\n      .given(\"an alligator exists\")\n      .uponReceiving(\"a request for alligator\")\n      .withRequest(method: .GET, path: \"/alligator\")\n      .willRespondWith(status: 200,\n                       headers: [\"Content-Type\": \"application/json\"],\n                       body: [ \"name\": \"Mary\" ])\n\n    // Run the test\n    animalMockService!.run(timeout: 60) { (testComplete) -\u003e Void in\n      self.animalServiceClient!.getAlligator { (response) -\u003e in\n        XCTAssertEqual(response.name, \"Mary\")\n        testComplete()\n      }\n    }\n  }\n  ...\n```\n\nAn optional `timeout` (seconds) parameter can be included on the run function. Defaults to 30 seconds.\n\n```swift\n...\n    // Run the test\n    animalMockService!.run(timeout: 60) { (testComplete) -\u003e Void in\n      self.animalServiceClient!.getAlligator { (response) -\u003e in\n        XCTAssertEqual(response.name, \"Mary\")\n        testComplete()\n      }\n    }\n```\n\nFor an example on how to test over `https` see [PactSSLSpec.swift][pact-ssl-spec].\n\n### Matching\n\nIn addition to verbatim value matching, you have 3 useful matching functions\nin the `Matcher` class that can increase expressiveness and reduce brittle test\ncases.\n\n* `Matcher.term(matcher, generate)` - tells Pact that the value should match using\na given regular expression, using `generate` in mock responses. `generate` must be\na string.\n* `Matcher.somethingLike(content)` - tells Pact that the value itself is not important, as long\nas the element _type_ (valid JSON number, string, object etc.) itself matches.\n* `Matcher.eachLike(content, min)` - tells Pact that the value should be an array type,\nconsisting of elements like those passed in. `min` must be \u003e= 1. `content` may\nbe a valid JSON value: e.g. strings, numbers and objects.\n\n*NOTE*: One caveat to note, is that you will need to use valid Ruby [regular expressions][regular-expressions] and double escape backslashes.\n\nSee the `PactSpecs.swift`, `PactObjectiveCTests.m` for examples on how to expect error responses, how to use query params, and Matchers.\n\nFor more on request / response matching, see [Matching][getting_started/matching].\n\n### Using in your CI\n\nXcode's _pre-actions_ and _post-actions_ do not honour non-zero script exits and therefore would not fail your build if publishing to a Pact Broker would fail. If you would like to upload your Pact files to a Pact Broker as part of your CI, we would suggest that you create a separate step in your CI workflow with that responsibility.\n\nSee [pact-ruby-standalone][pact-ruby-standalone-releases] page for installation instructions and how to use `pact-broker` client.\n\n### Verifying your client against the service you are integrating with\n\nIf your setup is correct and your tests run against the pack mock server, then you should see a log file here:\n`$YOUR_PROJECT/tmp/pact.log`\nAnd the generated pacts here:\n`$YOUR_PROJECT/tmp/pacts/...`\n\n[Publish][pact-publish-to-broker] your generated pact file(s) to your [Pact Broker][pact-broker] or a [Hosted Pact Broker][pactflow] so your _API provider_ can always retrieve them from one location, even when pacts change. Or even just by simply sending the pact file to your API provider devs so they can used them in their tests of their API responses. See [Verifying pacts][pact-verifying] for more information.\nFor an end-to-end example with a ruby back end service, have a look at the [KatKit example][pact-katkit-example].\n\nAlso, check out this article on [using a dockerized Node.js service][pact-dockerized-example] that uses provider states.\n\n## More reading\n\n- The Pact website [Pact](http://pact.io)\n- The pact mock server that the Swift library uses under the hood [Pact mock service][pact-mock-service]\n- A pact broker for managing the generated pact files (so you don't have to manually copy them around!) [Pact broker][pact-broker]\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](/CONTRIBUTING.md)\n\n[upgrading]: https://github.com/DiUS/pact-consumer-swift/wiki/Upgrading\n[pact-broker]: https://github.com/pact-foundation/pact_broker\n[pact-readme]: https://github.com/realestate-com-au/pact\n[pact-verifying]: https://docs.pact.io/getting_started/verifying_pacts\n[pact-spec-v2]: https://github.com/pact-foundation/pact-specification/tree/version-2\n[pact-spec-v3]: https://github.com/pact-foundation/pact-specification/tree/version-3\n[pact-swift]: https://github.com/surpher/PactSwift\n[pact-flexible-matching]: https://docs.pact.io/getting_started/matching\n[pact-publish-to-broker]: https://github.com/pact-foundation/pact_broker/wiki/Publishing-and-retrieving-pacts\n[pact-katkit-example]: https://github.com/andrewspinks/pact-mobile-preso\n[pact-dockerized-example]: https://medium.com/@rajatvig/ios-docker-and-consumer-driven-contract-testing-with-pact-d99b6bf4b09e#.ozcbbktzk\n[pact-mock-service]: https://github.com/bethesque/pact-mock_service\n[pact-ruby-standalone]: https://github.com/pact-foundation/pact-ruby-standalone\n[pact-ruby-standalone-releases]: https://github.com/pact-foundation/pact-ruby-standalone/releases\n[pact-ruby-standalone-homebrew]: https://github.com/pact-foundation/homebrew-pact-ruby-standalone\n[pact-mock-service-without-ruby]: https://github.com/DiUS/pact-consumer-js-dsl/wiki/Using-the-Pact-Mock-Service-without-Ruby\n[pact-ssl-spec]: Tests/PactConsumerSwiftTests/PactSSLSpecs.swift\n[regular-expressions]: http://ruby-doc.org/core-2.1.5/Regexp.html\n[matching]: http://docs.pact.io/documentation/matching.html\n[pact-swiftpm-example]: http://github.com/surpher/PactSwiftPMExample\n[build-swiftpm-example]: https://github.com/surpher/PactSwiftPMExample/actions?query=workflow%3ABuild\n[pact-objc-example]: https://github.com/andrewspinks/PactObjectiveCExample\n[build-objc-example]: https://travis-ci.org/andrewspinks/PactObjectiveCExample\n[pact-carthage-macos-example]: https://github.com/surpher/PactMacOSExample\n[build-carthage-macos-example]: https://github.com/surpher/PactMacOSExample/actions?query=workflow%3ABuild\n[pact-carthage-ios-example]: https://github.com/andrewspinks/PactSwiftExample\n[build-carthage-ios-example]: https://travis-ci.org/andrewspinks/PactSwiftExample\n[pact-microservices]: https://dius.com.au/2016/02/03/pact-101-getting-started-with-pact-and-consumer-driven-contract-testing/\n[swift-package-manager]: https://swift.org/package-manager/\n[pactflow]: https://pactflow.io\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdius%2Fpact-consumer-swift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdius%2Fpact-consumer-swift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdius%2Fpact-consumer-swift/lists"}