diff --git a/README.md b/README.md index 8a2caf9b8..f6dd7a8ab 100644 --- a/README.md +++ b/README.md @@ -452,6 +452,26 @@ publishing or retrieving Pact files to/from a Pact Broker: * `BrokerUsername` - the username for Pact Broker basic authentication. * `BrokerPassword` - the password for Pact Broker basic authentication. +### Splitting tests across multiple files + +Pact tests tend to be quite long, due to the need to be specific about request/response payloads. Often times it is nicer to be able to split your tests across multiple files for manageability. + +You have two options to achieve this feat: + +1. Set `PactFileWriteMode` to `"update"` when creating a `Pact` struct: + + This will allow you to have multiple independent tests for a given Consumer-Provider pair, without it clobbering previous interactions. + + See this [PR](https://github.com/pact-foundation/pact-js/pull/48) for background. + + _NOTE_: If using this approach, you *must* be careful to clear out existing pact files (e.g. `rm ./pacts/*.json`) before you run tests to ensure you don't have left over requests that are no longer relevent. + +1. Create a Pact test helper to orchestrate the setup and teardown of the mock service for multiple tests. + + In larger test bases, this can reduce test suite time and the amount of code you have to manage. + + See the JS [example](https://github.com/tarciosaraiva/pact-melbjs/blob/master/helper.js) and related [issue](https://github.com/pact-foundation/pact-js/issues/11) for more. + ### Output Logging Pact Go uses a simple log utility ([logutils](https://github.com/hashicorp/logutils)) diff --git a/dsl/mock_service.go b/dsl/mock_service.go index f52f66e81..718963d76 100644 --- a/dsl/mock_service.go +++ b/dsl/mock_service.go @@ -22,6 +22,14 @@ type MockService struct { // Provider name. Provider string + + // PactFileWriteMode specifies how to write to the Pact file, for the life + // of a Mock Service. + // "overwrite" will always truncate and replace the pact after each run + // "update" will append to the pact file, which is useful if your tests + // are split over multiple files and instantiations of a Mock Server + // See https://github.com/realestate-com-au/pact/blob/master/documentation/configuration.md#pactfile_write_mode + PactFileWriteMode string } // call sends a message to the Pact service @@ -84,16 +92,22 @@ func (m *MockService) Verify() error { // WritePact writes the pact file to disk. func (m *MockService) WritePact() error { log.Println("[DEBUG] mock service write pact") + if m.Consumer == "" || m.Provider == "" { return errors.New("Consumer and Provider name need to be provided") } - pact := map[string]map[string]string{ + if m.PactFileWriteMode == "" { + m.PactFileWriteMode = "overwrite" + } + + pact := map[string]interface{}{ "consumer": map[string]string{ "name": m.Consumer, }, "provider": map[string]string{ "name": m.Provider, }, + "pactFileWriteMode": m.PactFileWriteMode, } url := fmt.Sprintf("%s/pact", m.BaseURL) diff --git a/dsl/pact.go b/dsl/pact.go index 91c89daea..9ac23557f 100644 --- a/dsl/pact.go +++ b/dsl/pact.go @@ -48,6 +48,14 @@ type Pact struct { // Defaults to `/pacts`. PactDir string + // PactFileWriteMode specifies how to write to the Pact file, for the life + // of a Mock Service. + // "overwrite" will always truncate and replace the pact after each run + // "update" will append to the pact file, which is useful if your tests + // are split over multiple files and instantiations of a Mock Server + // See https://github.com/realestate-com-au/pact/blob/master/documentation/configuration.md#pactfile_write_mode + PactFileWriteMode string + // Specify which version of the Pact Specification should be used (1 or 2). // Defaults to 2. SpecificationVersion int @@ -192,9 +200,10 @@ func (p *Pact) WritePact() error { p.Setup(true) log.Printf("[DEBUG] pact write Pact file") mockServer := MockService{ - BaseURL: fmt.Sprintf("http://%s:%d", p.Host, p.Server.Port), - Consumer: p.Consumer, - Provider: p.Provider, + BaseURL: fmt.Sprintf("http://%s:%d", p.Host, p.Server.Port), + Consumer: p.Consumer, + Provider: p.Provider, + PactFileWriteMode: p.PactFileWriteMode, } err := mockServer.WritePact() if err != nil {