PACT-JS - 提供商合同验证 error/failure - PactFlow
PACT-JS - Provider contract verification error/failure - PactFlow
我正在拔头发。我创建了一个 Pact-JS 测试框架来测试我的简单 NodeJS 应用程序。我将在下面显示所有代码。我使用 PactFlow 来托管我的合同文件(由 运行 我的消费者测试生成)。问题是当我 运行 我的提供商代码失败时。我收到以下错误(我将 post 下面更详细的错误)) - `assert_success!': Error retrieving https://zaizi.pactflow.io/pacts/provider/Clients%20Service/for-verification status=404
消费者测试代码 - pact.consumer.spec.js
const { Matchers, Publisher } = require("@pact-foundation/pact")
const Pact = require("@pact-foundation/pact").Pact
const { getClients, getClient, postClient } = require("../../src/consumer")
const path = require("path")
// mock provider setup
const mockProvider = new Pact({
port: 8081,
log: path.resolve(process.cwd(), "__tests__/logs", "mock-provider.log"), // log file location and name
dir: path.resolve(process.cwd(), "__tests__/pacts"), // location where pact contract will be saved
spec: 2,
logLevel: 'INFO',
pactfileWriteMode: "overwrite",
consumer: "pact-consumer",
provider: "pact-provider"
})
describe("Pact for Clients Service API", () => {
beforeAll(() => mockProvider.setup()); // Start the Mock Server and wait for it to be available
afterEach(() => mockProvider.verify()); // Verifies that all interactions specified
afterAll(() => mockProvider.finalize()); // Records the interactions between the Mock Server into the pact file and shuts it down
describe('given there are clients', () => {
describe('when a request is made to GET all clients', () => {
// GET_EXPECTED_BODY = [
// { "firstName": "Lisa", "lastName": "Simpson", "age": 8, "id": 1 },
// { "firstName": "Wonder", "lastName": "Woman", "age": 30, "id": 2 },
// { "firstName": "Homer", "lastName": "Simpson", "age": 39, "id": 3 }]
const GET_EXPECTED_BODY = [{
"firstName": "Lisa",
"lastName": "Simpson",
"age": 8,
"id": 1
},
{
"firstName": "Wonder",
"lastName": "Woman",
"age": 30,
"id": 2
},
{
"firstName": "Homer",
"lastName": "Simpson",
"age": 39,
"id": 3
}]
beforeEach(() => {
const interaction = {
state: "i have a list of clients",
uponReceiving: "a request for all clients",
withRequest: {
method: "GET",
path: "/clients",
headers: {
Accept: "application/json, text/plain, */*",
},
},
willRespondWith: {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
body: GET_EXPECTED_BODY,
},
}
return mockProvider.addInteraction(interaction)
})
it('will return a list of clients', async() => {
// make request to the Pact mock server to get all clients
const response = await getClients()
expect(response.headers['content-type']).toBe("application/json; charset=utf-8")
expect(response.data).toEqual(GET_EXPECTED_BODY)
expect(response.status).toEqual(200)
})
})
})
})
提供商测试代码 - pact.provider.spec.js
const path = require("path")
const { Verifier } = require("@pact-foundation/pact")
const { server, importData } = require("../../src/provider")
require('dotenv').config()
jest.setTimeout(30000);
describe("Clients Service Pact verification", () => {
const port = 8081
let opts = {
provider: "Clients Service",
logLevel: "DEBUG",
providerBaseUrl: `http://localhost:${port}`,
// pactUrls: [path.resolve(process.cwd(), "./__tests__/pacts/pact-consumer-pact-provider.json")],
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
pactBrokerToken: process.env.PACT_BROKER_TOKEN,
consumerVersionTags: ["pact-consumer"],
providerVersionTags: ["pact-provider"],
publishVerificationResult: false,
providerVersion: "1.0.0"
}
// Start real provider server
beforeAll(async () => {
server.listen(port, () => {
importData()
console.log(`Provider listening on http://localhost:${port}`)
})
})
it("validates the expectations of the clients service", () => {
return new Verifier(opts).verifyProvider().then(output => {
console.log("Pact Verification Complete!")
console.log(output)
})
})
afterAll(async ()=> {
server.close();
})
// it('should validate the expectations of Order Web', () => {
// return new Verifier().verifyProvider(opts)
// })
})
我的契约在这里:-
{
"consumer": {
"name": "pact-consumer"
},
"provider": {
"name": "pact-provider"
},
"interactions": [
{
"description": "a request for all clients",
"providerState": "i have a list of clients",
"request": {
"method": "GET",
"path": "/clients",
"headers": {
"Accept": "application/json, text/plain, */*"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": [
{
"firstName": "Lisa",
"lastName": "Simpson",
"age": 8,
"id": 1
},
{
"firstName": "Wonder",
"lastName": "Woman",
"age": 30,
"id": 2
},
{
"firstName": "Homer",
"lastName": "Simpson",
"age": 39,
"id": 3
}
]
}
}
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
这是我的 PactFlow:-
详细错误日志:-
[2022-04-13 16:57:12.453 +0000] INFO (15316 on DESKTOP-TJVM91P): pact@9.17.3: Verifying provider
console.log
Provider listening on http://localhost:8081
at Server.<anonymous> (__tests__/provider/pact.provider.spec.js:28:21)
[2022-04-13 16:57:12.481 +0000] INFO (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Verifying Pacts.
[2022-04-13 16:57:12.483 +0000] INFO (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Verifying Pact Files
[2022-04-13 16:57:12.484 +0000] DEBUG (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Starting pact binary 'D:\p\pact-nodejs-demo\node_modules\@pact-foundation\pact-node\standalone\win32-1.88.83\pact\bin\pact-provider-verifier.bat', with arguments [--provider-states-setup-url http://localhost:59761/_pactSetup --provider Clients Service --log-level DEBUG --provider-base-url http://localhost:59761 --pact-broker-base-url https://******.pactflow.io --broker-token 1iB-FQbUuvpxce6QX-DBTQ --consumer-version-tag pact-consumer --provider-version-tag pact-provider --publish-verification-results false --provider-app-version 1.0.0 --verbose true]
[2022-04-13 16:57:12.491 +0000] DEBUG (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Created 'D:\p\pact-nodejs-demo\node_modules\@pact-foundation\pact-node\standalone\win32-1.88.83\pact\bin\pact-provider-verifier.bat' process with PID: 10524
FAIL __tests__/provider/pact.provider.spec.js (9.938s)
Clients Service Pact verification
× validates the expectations of the clients service (8022ms)
● Clients Service Pact verification › validates the expectations of the clients service
D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/hal/entity.rb:102:in `assert_success!': Error retrieving https://******.pactflow.io/pacts/provider/Clients%20Service/for-verification status=404 (Pact::Hal::ErrorResponseReturned)
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/hal/link.rb:65:in `post!'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:75:in `pacts_for_verification_entity'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:61:in `pacts_for_verification'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:44:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:38:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker.rb:18:in `fetch_pact_uris_for_verification'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:46:in `pacts_for_verification'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:39:in `pacts_urls_from_broker'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:26:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:10:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:211:in `all_pact_urls'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:225:in `warn_empty_pact_set'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:40:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:35:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/cli/verify.rb:49:in `verify'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor/command.rb:27:in
`run'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/cli/custom_thor.rb:17:in `start'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/app/pact-provider-verifier.rb:33:in `<main>'
opening connection to ******.pactflow.io:443...
opened
starting SSL for ******.pactflow.io:443...
SSL established
<- "GET / HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: application/hal+json\r\nUser-Agent: Ruby\r\nAuthorization: [redacted]\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "Date: Wed, 13 Apr 2022 16:57:19 GMT\r\n"
-> "Content-Type: application/hal+json;charset=utf-8\r\n"
-> "Content-Length: 5555\r\n"
-> "Connection: keep-alive\r\n"
-> "Vary: Accept\r\n"
-> "Server: Webmachine-Ruby/1.6.0 Rack/1.3\r\n"
-> "X-Pact-Broker-Version: 2.98.0\r\n"
-> "X-Pact-Broker-Git-Sha: 3a08d128\r\n"
-> "X-Pactflow-Git-Sha: 85e7754e3\r\n"
-> "X-Content-Type-Options: nosniff\r\n"
-> "Strict-Transport-Security: max-age=63072000; includeSubDomains; preload\r\n"
-> "X-Request-Id: cb35bba1d72c207abc7d787cbb5f4473\r\n"
-> "\r\n"
reading 5555 bytes...
-> "{\"_links\":{\"self\":{\"href\":\"https://******.pactflow.io\",\"title\":\"Index\",\"templated\":false},\"pb:publish-pact\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/consumer/{consumer}/version/{consumerApplicationVersion}\",\"title\":\"Publish a pact\",\"templated\":true},\"pb:publish-contracts\":{\"href\":\"https://******.pactflow.io/contracts/publish\",\"title\":\"Publish contracts\",\"templated\":false},\"pb:latest-pact-versions\":{\"href\":\"https://******.pactflow.io/pacts/latest\",\"title\":\"Latest pact versions\",\"templated\":false},\"pb:tagged-pact-versions\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/consumer/{consumer}/tag/{tag}\",\"title\":\"All versions of a pact for a given consumer, provider and consumer version tag\",\"templated\":false},\"pb:pacticipants\":{\"href\":\"https://******.pactflow.io/pacticipants\",\"title\":\"Pacticipants\",\"templated\":false},\"pb:pacticipant\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}\",\"title\":\"Fetch pacticipant by name\",\"templated\":true},\"pb:latest-provider-pacts\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/latest\",\"title\":\"Latest pacts by provider\",\"templated\":true},\"pb:latest-provider-pacts-with-tag\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/latest/{tag}\",\"title\":\"Latest pacts for provider with the specified tag\",\"templated\":true},\"pb:provider-pacts-with-tag\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/tag/{tag}\",\"title\":\"All pact versions for the provider with the specified consumer version tag\",\"templated\":true},\"pb:provider-pacts\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}\",\"title\":\"All pact versions for the specified provider\",\"templated\":true},\"pb:latest-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/latest-version\",\"title\":\"Latest pacticipant version\",\"templated\":true},\"pb:latest-tagged-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/latest-version/{tag}\",\"title\":\"Latest pacticipant version with the specified tag\",\"templated\":true},\"pb:webhooks\":{\"href\":\"https://******.pactflow.io/webhooks\",\"title\":\"Webhooks\",\"templated\":false},\"pb:webhook\":{\"href\":\"https://******.pactflow.io/webhooks/{uuid}\",\"title\":\"Webhook\",\"templated\":true},\"pb:integrations\":{\"href\":\"https://******.pactflow.io/integrations\",\"title\":\"Integrations\",\"templated\":false},\"pb:pacticipant-version-tag\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/versions/{version}/tags/{tag}\",\"title\":\"Get, create or delete a tag for a pacticipant version\",\"templated\":true},\"pb:pacticipant-branch-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/branches/{branch}/versions/{version}\",\"title\":\"Get or add/create a pacticipant version for a branch\",\"templated\":true},\"pb:pacticipant-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/versions/{version}\",\"title\":\"Get, create or delete a pacticipant version\",\"templated\":true},\"pb:metrics\":{\"href\":\"https://******.pactflow.io/metrics\",\"title\":\"Get Pact Broker metrics\"},\"pb:can-i-deploy-pacticipant-version-to-tag\":{\"href\":\"https://******.pactflow.io/can-i-deploy?pacticipant={pacticipant}\u0026version={version}\u0026to={tag}\",\"title\":\"Determine if an application version can be safely deployed to an environment identified by the given tag\",\"templated\":true},\"pb:can-i-deploy-pacticipant-version-to-environment\":{\"href\":\"https://******.pactflow.io/can-i-deploy?pacticipant={pacticipant}\u0026version={version}\u0026environment={environment}\",\"title\":\"Determine if an application version can be safely deployed to an environment\",\"templated\":true},\"pb:provider-pacts-for-verification\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/for-verification\",\"title\":\"Pact versions to be verified for the specified provider\",\"templated\":true},\"beta:provider-pacts-for-verification\":{\"name\":\"beta\",\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/for-verification\",\"title\":\"DEPRECATED - please use pb:provider-pacts-for-verification\",\"templated\":true},\"curies\":[{\"name\":\"pb\",\"href\":\"https://******.pactflow.io/doc/{rel}?context=index\",\"templated\":true},{\"name\":\"beta\",\"href\":\"https://******.pactflow.io/doc/{rel}?context=index\",\"templated\":true}],\"pb:environments\":{\"title\":\"Environments\",\"href\":\"https://******.pactflow.io/environments\",\"templated\":false},\"pb:environment\":{\"title\":\"Environment\",\"href\":\"https://******.pactflow.io/environments/{uuid}\",\"templated\":true},\"pb:api-tokens\":{\"href\":\"https://******.pactflow.io/settings/tokens\",\"title\":\"API tokens\",\"templated\":false},\"pb:audit\":{\"href\":\"https://******.pactflow.io/audit\",\"title\":\"Audit trail\",\"templated\":false},\"pb:secrets\":{\"href\":\"https://******.pactflow.io/secrets\",\"title\":\"Secrets\",\"templated\":false},\"pf:admin-users\":{\"href\":\"https://******.pactflow.io/admin/users\",\"title\":\"Users\",\"templated\":false},\"pf:admin-teams\":{\"href\":\"https://******.pactflow.io/admin/teams\",\"title\":\"Teams\",\"templated\":false},\"pf:admin-system-accounts\":{\"href\":\"https://******.pactflow.io/admin/system-accounts\",\"title\":\"System accounts\",\"templated\":false},\"pf:admin-roles\":{\"href\":\"https://******.pactflow.io/admin/roles\",\"title\":\"Roles\",\"templated\":false},\"pf:admin-permissions\":{\"href\":\"https://******.pactflow.io/admin/permissions\",\"title\":\"Permissions\",\"templated\":false},\"pf:admin-authentication-settings\":{\"href\":\"https://******.pactflow.io/admin/tenant/authentication-settings\",\"title\":\"Authentication Settings\",\"templated\":false},\"pf:user-allocations\":{\"href\":\"https://******.pactflow.io/tenant/limits\",\"title\":\"User Allocations\",\"templated\":false}}}"
很简单。您已将消费者测试中的提供者(以及合同中的内容)定义为 pact-provider
.
然而,在您的提供商测试中,它被称为 Clients Service
。
当您的提供者测试试图发现合同时,它使用提供者名称作为键。因为没有名为 Clients Service
的提供程序,所以它得到一个 404
.
两者都
- 将消费者中的提供商名称更新为
Clients Service
(并删除旧集成)
- 将提供商名称更新为
pact-provider
(1. 似乎是正确的做法)
我正在拔头发。我创建了一个 Pact-JS 测试框架来测试我的简单 NodeJS 应用程序。我将在下面显示所有代码。我使用 PactFlow 来托管我的合同文件(由 运行 我的消费者测试生成)。问题是当我 运行 我的提供商代码失败时。我收到以下错误(我将 post 下面更详细的错误)) - `assert_success!': Error retrieving https://zaizi.pactflow.io/pacts/provider/Clients%20Service/for-verification status=404
消费者测试代码 - pact.consumer.spec.js
const { Matchers, Publisher } = require("@pact-foundation/pact")
const Pact = require("@pact-foundation/pact").Pact
const { getClients, getClient, postClient } = require("../../src/consumer")
const path = require("path")
// mock provider setup
const mockProvider = new Pact({
port: 8081,
log: path.resolve(process.cwd(), "__tests__/logs", "mock-provider.log"), // log file location and name
dir: path.resolve(process.cwd(), "__tests__/pacts"), // location where pact contract will be saved
spec: 2,
logLevel: 'INFO',
pactfileWriteMode: "overwrite",
consumer: "pact-consumer",
provider: "pact-provider"
})
describe("Pact for Clients Service API", () => {
beforeAll(() => mockProvider.setup()); // Start the Mock Server and wait for it to be available
afterEach(() => mockProvider.verify()); // Verifies that all interactions specified
afterAll(() => mockProvider.finalize()); // Records the interactions between the Mock Server into the pact file and shuts it down
describe('given there are clients', () => {
describe('when a request is made to GET all clients', () => {
// GET_EXPECTED_BODY = [
// { "firstName": "Lisa", "lastName": "Simpson", "age": 8, "id": 1 },
// { "firstName": "Wonder", "lastName": "Woman", "age": 30, "id": 2 },
// { "firstName": "Homer", "lastName": "Simpson", "age": 39, "id": 3 }]
const GET_EXPECTED_BODY = [{
"firstName": "Lisa",
"lastName": "Simpson",
"age": 8,
"id": 1
},
{
"firstName": "Wonder",
"lastName": "Woman",
"age": 30,
"id": 2
},
{
"firstName": "Homer",
"lastName": "Simpson",
"age": 39,
"id": 3
}]
beforeEach(() => {
const interaction = {
state: "i have a list of clients",
uponReceiving: "a request for all clients",
withRequest: {
method: "GET",
path: "/clients",
headers: {
Accept: "application/json, text/plain, */*",
},
},
willRespondWith: {
status: 200,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
body: GET_EXPECTED_BODY,
},
}
return mockProvider.addInteraction(interaction)
})
it('will return a list of clients', async() => {
// make request to the Pact mock server to get all clients
const response = await getClients()
expect(response.headers['content-type']).toBe("application/json; charset=utf-8")
expect(response.data).toEqual(GET_EXPECTED_BODY)
expect(response.status).toEqual(200)
})
})
})
})
提供商测试代码 - pact.provider.spec.js
const path = require("path")
const { Verifier } = require("@pact-foundation/pact")
const { server, importData } = require("../../src/provider")
require('dotenv').config()
jest.setTimeout(30000);
describe("Clients Service Pact verification", () => {
const port = 8081
let opts = {
provider: "Clients Service",
logLevel: "DEBUG",
providerBaseUrl: `http://localhost:${port}`,
// pactUrls: [path.resolve(process.cwd(), "./__tests__/pacts/pact-consumer-pact-provider.json")],
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
pactBrokerToken: process.env.PACT_BROKER_TOKEN,
consumerVersionTags: ["pact-consumer"],
providerVersionTags: ["pact-provider"],
publishVerificationResult: false,
providerVersion: "1.0.0"
}
// Start real provider server
beforeAll(async () => {
server.listen(port, () => {
importData()
console.log(`Provider listening on http://localhost:${port}`)
})
})
it("validates the expectations of the clients service", () => {
return new Verifier(opts).verifyProvider().then(output => {
console.log("Pact Verification Complete!")
console.log(output)
})
})
afterAll(async ()=> {
server.close();
})
// it('should validate the expectations of Order Web', () => {
// return new Verifier().verifyProvider(opts)
// })
})
我的契约在这里:-
{
"consumer": {
"name": "pact-consumer"
},
"provider": {
"name": "pact-provider"
},
"interactions": [
{
"description": "a request for all clients",
"providerState": "i have a list of clients",
"request": {
"method": "GET",
"path": "/clients",
"headers": {
"Accept": "application/json, text/plain, */*"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": [
{
"firstName": "Lisa",
"lastName": "Simpson",
"age": 8,
"id": 1
},
{
"firstName": "Wonder",
"lastName": "Woman",
"age": 30,
"id": 2
},
{
"firstName": "Homer",
"lastName": "Simpson",
"age": 39,
"id": 3
}
]
}
}
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
这是我的 PactFlow:-
详细错误日志:-
[2022-04-13 16:57:12.453 +0000] INFO (15316 on DESKTOP-TJVM91P): pact@9.17.3: Verifying provider
console.log
Provider listening on http://localhost:8081
at Server.<anonymous> (__tests__/provider/pact.provider.spec.js:28:21)
[2022-04-13 16:57:12.481 +0000] INFO (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Verifying Pacts.
[2022-04-13 16:57:12.483 +0000] INFO (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Verifying Pact Files
[2022-04-13 16:57:12.484 +0000] DEBUG (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Starting pact binary 'D:\p\pact-nodejs-demo\node_modules\@pact-foundation\pact-node\standalone\win32-1.88.83\pact\bin\pact-provider-verifier.bat', with arguments [--provider-states-setup-url http://localhost:59761/_pactSetup --provider Clients Service --log-level DEBUG --provider-base-url http://localhost:59761 --pact-broker-base-url https://******.pactflow.io --broker-token 1iB-FQbUuvpxce6QX-DBTQ --consumer-version-tag pact-consumer --provider-version-tag pact-provider --publish-verification-results false --provider-app-version 1.0.0 --verbose true]
[2022-04-13 16:57:12.491 +0000] DEBUG (15316 on DESKTOP-TJVM91P): pact-node@10.17.2: Created 'D:\p\pact-nodejs-demo\node_modules\@pact-foundation\pact-node\standalone\win32-1.88.83\pact\bin\pact-provider-verifier.bat' process with PID: 10524
FAIL __tests__/provider/pact.provider.spec.js (9.938s)
Clients Service Pact verification
× validates the expectations of the clients service (8022ms)
● Clients Service Pact verification › validates the expectations of the clients service
D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/hal/entity.rb:102:in `assert_success!': Error retrieving https://******.pactflow.io/pacts/provider/Clients%20Service/for-verification status=404 (Pact::Hal::ErrorResponseReturned)
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/hal/link.rb:65:in `post!'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:75:in `pacts_for_verification_entity'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:61:in `pacts_for_verification'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:44:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb:38:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-1.62.0/lib/pact/pact_broker.rb:18:in `fetch_pact_uris_for_verification'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:46:in `pacts_for_verification'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:39:in `pacts_urls_from_broker'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:26:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/aggregate_pact_configs.rb:10:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:211:in `all_pact_urls'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:225:in `warn_empty_pact_set'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:40:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/app.rb:35:in `call'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/cli/verify.rb:49:in `verify'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor/command.rb:27:in
`run'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/vendor/ruby/2.2.0/gems/pact-provider-verifier-1.36.1/lib/pact/provider_verifier/cli/custom_thor.rb:17:in `start'
from D:/p/pact-nodejs-demo/node_modules/@pact-foundation/pact-node/standalone/win32-1.88.83/pact/lib/app/pact-provider-verifier.rb:33:in `<main>'
opening connection to ******.pactflow.io:443...
opened
starting SSL for ******.pactflow.io:443...
SSL established
<- "GET / HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: application/hal+json\r\nUser-Agent: Ruby\r\nAuthorization: [redacted]\r\n"
-> "HTTP/1.1 200 OK\r\n"
-> "Date: Wed, 13 Apr 2022 16:57:19 GMT\r\n"
-> "Content-Type: application/hal+json;charset=utf-8\r\n"
-> "Content-Length: 5555\r\n"
-> "Connection: keep-alive\r\n"
-> "Vary: Accept\r\n"
-> "Server: Webmachine-Ruby/1.6.0 Rack/1.3\r\n"
-> "X-Pact-Broker-Version: 2.98.0\r\n"
-> "X-Pact-Broker-Git-Sha: 3a08d128\r\n"
-> "X-Pactflow-Git-Sha: 85e7754e3\r\n"
-> "X-Content-Type-Options: nosniff\r\n"
-> "Strict-Transport-Security: max-age=63072000; includeSubDomains; preload\r\n"
-> "X-Request-Id: cb35bba1d72c207abc7d787cbb5f4473\r\n"
-> "\r\n"
reading 5555 bytes...
-> "{\"_links\":{\"self\":{\"href\":\"https://******.pactflow.io\",\"title\":\"Index\",\"templated\":false},\"pb:publish-pact\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/consumer/{consumer}/version/{consumerApplicationVersion}\",\"title\":\"Publish a pact\",\"templated\":true},\"pb:publish-contracts\":{\"href\":\"https://******.pactflow.io/contracts/publish\",\"title\":\"Publish contracts\",\"templated\":false},\"pb:latest-pact-versions\":{\"href\":\"https://******.pactflow.io/pacts/latest\",\"title\":\"Latest pact versions\",\"templated\":false},\"pb:tagged-pact-versions\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/consumer/{consumer}/tag/{tag}\",\"title\":\"All versions of a pact for a given consumer, provider and consumer version tag\",\"templated\":false},\"pb:pacticipants\":{\"href\":\"https://******.pactflow.io/pacticipants\",\"title\":\"Pacticipants\",\"templated\":false},\"pb:pacticipant\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}\",\"title\":\"Fetch pacticipant by name\",\"templated\":true},\"pb:latest-provider-pacts\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/latest\",\"title\":\"Latest pacts by provider\",\"templated\":true},\"pb:latest-provider-pacts-with-tag\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/latest/{tag}\",\"title\":\"Latest pacts for provider with the specified tag\",\"templated\":true},\"pb:provider-pacts-with-tag\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/tag/{tag}\",\"title\":\"All pact versions for the provider with the specified consumer version tag\",\"templated\":true},\"pb:provider-pacts\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}\",\"title\":\"All pact versions for the specified provider\",\"templated\":true},\"pb:latest-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/latest-version\",\"title\":\"Latest pacticipant version\",\"templated\":true},\"pb:latest-tagged-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/latest-version/{tag}\",\"title\":\"Latest pacticipant version with the specified tag\",\"templated\":true},\"pb:webhooks\":{\"href\":\"https://******.pactflow.io/webhooks\",\"title\":\"Webhooks\",\"templated\":false},\"pb:webhook\":{\"href\":\"https://******.pactflow.io/webhooks/{uuid}\",\"title\":\"Webhook\",\"templated\":true},\"pb:integrations\":{\"href\":\"https://******.pactflow.io/integrations\",\"title\":\"Integrations\",\"templated\":false},\"pb:pacticipant-version-tag\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/versions/{version}/tags/{tag}\",\"title\":\"Get, create or delete a tag for a pacticipant version\",\"templated\":true},\"pb:pacticipant-branch-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/branches/{branch}/versions/{version}\",\"title\":\"Get or add/create a pacticipant version for a branch\",\"templated\":true},\"pb:pacticipant-version\":{\"href\":\"https://******.pactflow.io/pacticipants/{pacticipant}/versions/{version}\",\"title\":\"Get, create or delete a pacticipant version\",\"templated\":true},\"pb:metrics\":{\"href\":\"https://******.pactflow.io/metrics\",\"title\":\"Get Pact Broker metrics\"},\"pb:can-i-deploy-pacticipant-version-to-tag\":{\"href\":\"https://******.pactflow.io/can-i-deploy?pacticipant={pacticipant}\u0026version={version}\u0026to={tag}\",\"title\":\"Determine if an application version can be safely deployed to an environment identified by the given tag\",\"templated\":true},\"pb:can-i-deploy-pacticipant-version-to-environment\":{\"href\":\"https://******.pactflow.io/can-i-deploy?pacticipant={pacticipant}\u0026version={version}\u0026environment={environment}\",\"title\":\"Determine if an application version can be safely deployed to an environment\",\"templated\":true},\"pb:provider-pacts-for-verification\":{\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/for-verification\",\"title\":\"Pact versions to be verified for the specified provider\",\"templated\":true},\"beta:provider-pacts-for-verification\":{\"name\":\"beta\",\"href\":\"https://******.pactflow.io/pacts/provider/{provider}/for-verification\",\"title\":\"DEPRECATED - please use pb:provider-pacts-for-verification\",\"templated\":true},\"curies\":[{\"name\":\"pb\",\"href\":\"https://******.pactflow.io/doc/{rel}?context=index\",\"templated\":true},{\"name\":\"beta\",\"href\":\"https://******.pactflow.io/doc/{rel}?context=index\",\"templated\":true}],\"pb:environments\":{\"title\":\"Environments\",\"href\":\"https://******.pactflow.io/environments\",\"templated\":false},\"pb:environment\":{\"title\":\"Environment\",\"href\":\"https://******.pactflow.io/environments/{uuid}\",\"templated\":true},\"pb:api-tokens\":{\"href\":\"https://******.pactflow.io/settings/tokens\",\"title\":\"API tokens\",\"templated\":false},\"pb:audit\":{\"href\":\"https://******.pactflow.io/audit\",\"title\":\"Audit trail\",\"templated\":false},\"pb:secrets\":{\"href\":\"https://******.pactflow.io/secrets\",\"title\":\"Secrets\",\"templated\":false},\"pf:admin-users\":{\"href\":\"https://******.pactflow.io/admin/users\",\"title\":\"Users\",\"templated\":false},\"pf:admin-teams\":{\"href\":\"https://******.pactflow.io/admin/teams\",\"title\":\"Teams\",\"templated\":false},\"pf:admin-system-accounts\":{\"href\":\"https://******.pactflow.io/admin/system-accounts\",\"title\":\"System accounts\",\"templated\":false},\"pf:admin-roles\":{\"href\":\"https://******.pactflow.io/admin/roles\",\"title\":\"Roles\",\"templated\":false},\"pf:admin-permissions\":{\"href\":\"https://******.pactflow.io/admin/permissions\",\"title\":\"Permissions\",\"templated\":false},\"pf:admin-authentication-settings\":{\"href\":\"https://******.pactflow.io/admin/tenant/authentication-settings\",\"title\":\"Authentication Settings\",\"templated\":false},\"pf:user-allocations\":{\"href\":\"https://******.pactflow.io/tenant/limits\",\"title\":\"User Allocations\",\"templated\":false}}}"
很简单。您已将消费者测试中的提供者(以及合同中的内容)定义为 pact-provider
.
然而,在您的提供商测试中,它被称为 Clients Service
。
当您的提供者测试试图发现合同时,它使用提供者名称作为键。因为没有名为 Clients Service
的提供程序,所以它得到一个 404
.
两者都
- 将消费者中的提供商名称更新为
Clients Service
(并删除旧集成) - 将提供商名称更新为
pact-provider
(1. 似乎是正确的做法)