pact-foundation / pact-js Goto Github PK
View Code? Open in Web Editor NEWJS version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.
Home Page: https://pact.io
License: Other
JS version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.
Home Page: https://pact.io
License: Other
Is it possible to add two different interactions that only differ by query string. Here's an example of what I'm trying to accomplish:
projectsProvider.addInteraction({ uponReceiving: 'a request for employee', withRequest: { method: 'get', path: '/EmployeeApi/api/organizations/0/employees' }
versus
projectsProvider.addInteraction({ uponReceiving: 'a request for employee with emails', withRequest: { method: 'get', path: '/EmployeeApi/api/organizations/0/employees', query: { 'include': 'emails' } }
Error:
Failed: Actual interactions do not match expected interactions for mock MockService.
Missing requests:
GET /EmployeeApi/api/organizations/0/employees?include=emails
When running the jest example I'm getting
Unhandled promise rejection { Error: connect ECONNREFUSED 127.0.0.1:8989 at Object.exports._errnoException (util.js:1050:11) at exports._exceptionWithHostPort (util.js:1073:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1093:14) code: 'ECONNREFUSED', errno: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 8989, config: { transformRequest: { '0': [Function: transformRequest] }, transformResponse: { '0': [Function: transformResponse] }, headers: { Accept: 'application/json', 'User-Agent': 'axios/0.14.0' }, timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, validateStatus: [Function: validateStatus], method: 'GET', baseURL: 'http://localhost:8989', url: 'http://localhost:8989/dogs', data: undefined }, response: undefined }
Has anyone seen anything similar?
I've cloned the repo and followed the README but am still seeing this. Non-jest examples are passing. I can see the pact server come up on that port and get torn down at the end.
Environment:
OSX
node 7.10
Hygiene task - add an npm 5+ package-lock.json
file.
Creating a general pact-web
module that can be used in Browser environments (e.g. Karma, Protractor etc.) that doesn't rely on underlying Ruby libraries would be very beneficial, and enable use cases previously available from the deprecated pact-consumer-js-dsl.
Perhaps a flag that prevents the import could be one option?
See #20.
I can't get the provided Jest example to run in isolation.
This is the output I get:
$ npm test
> [email protected] test ~/Projects/spikes/pact-js/examples/jest
> jest
FAIL __tests__/index.spec.js
● Test suite failed to run
Couldn't find preset "es2015" relative to directory "~/Projects/spikes/pact-js"
at node_modules/babel-core/lib/transformation/file/options/option-manager.js:299:19
at Array.map (native)
Test Summary
› Ran all tests.
› 1 test suite failed, 0 tests passed (0 total in 1 test suite, run time 0.351s)
npm ERR! Test failed. See above for more details.
This is on a Mac running Node 7.4.0.
It would be helpful if there was a read me of how to set it up properly.
Hi,
I am trying to start doing CDD on my JS application. I am trying to create the most simple consumer pact, but when I call
mockServer.start().then(() => {
provider = Pact({consumer: 'client', provider: 'service', port: 1234});
done();
});
It never gets inside the then
, so I am assuming the promise never gets resolved. I am using Jest that uses Jasmine behind the scene. I wonder if you have any clue of how could I debug this network issue ( if it is that ).
this is my test file
import Pact from 'pact';
import path from "path";
import chaiAsPromised from "chai-as-promised";
import pactWrapper from "@pact-foundation/pact-node";
import chai, {expect} from "chai";
import request from 'superagent';
chai.use(chaiAsPromised);
describe("see all dog", () => {
var provider, mockServer;
beforeAll(() =>{
mockServer = pactWrapper.createServer({
port: 1234,
host: "localhost",
log: path.resolve(process.cwd(), 'logs', 'mockserver-integration.log'),
dir: path.resolve(process.cwd(), 'pacts'),
consumer: "client",
provider: "service",
spec: 2
});
});
afterAll(() => {
pactWrapper.removeAllServers();
});
beforeEach((done) => {
mockServer.start().then(() => {
provider = Pact({consumer: 'client', provider: 'service', port: 1234});
done();
});
});
afterEach((done) => {
mockServer.delete().then(() => {
done();
});
});
describe("test", () => {
describe("test", () => {
beforeEach((done) => {
provider.addInteraction({
state: 'I want to see my dogs',
uponReceiving: 'a request to get dogs',
withRequest: {
method: 'GET',
path: '/dogs',
headers: {'Accept': 'application/json'}
},
willRespondWith: {
status: 200,
headers: {'Content-Type': 'application/json'},
body: {}
}
}).then(() => done());
});
afterEach((done) => {
provider.finalize().then(() => done())
});
it('successfully verifies', (done) => {
const verificationPromise = request
.get('http://localhost:1234/dogs')
.set({ 'Accept': 'application/json' })
.then(provider.verify);
expect(verificationPromise).to.eventually.eql(JSON.stringify({})).notify(done)
})
});
});
});
and when I run test I get
● see all dog › test › test › it successfully verifies
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at Timeout.e [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:477:19)
at tryOnTimeout (timers.js:232:11)
at Timer.listOnTimeout (timers.js:202:5)
- TypeError: Cannot read property 'addInteraction' of undefined
at Object.<anonymous> (app/components/Dogs/__tests__/clientTest.js:47:25)
at Timeout.e (node_modules/jsdom/lib/jsdom/browser/Window.js:477:19)
at tryOnTimeout (timers.js:232:11)
at Timer.listOnTimeout (timers.js:202:5)
- TypeError: Cannot read property 'verify' of undefined
at Object.<anonymous> (app/components/Dogs/__tests__/clientTest.js:71:30)
at Timeout.e (node_modules/jsdom/lib/jsdom/browser/Window.js:477:19)
at tryOnTimeout (timers.js:232:11)
at Timer.listOnTimeout (timers.js:202:5)
- TypeError: Cannot read property 'finalize' of undefined
at Object.<anonymous> (app/components/Dogs/__tests__/clientTest.js:64:25)
at Timeout.e (node_modules/jsdom/lib/jsdom/browser/Window.js:477:19)
at tryOnTimeout (timers.js:232:11)
at Timer.listOnTimeout (timers.js:202:5)
1 test failed, 0 tests passed (1 total in 1 test suite, run time 6.208s)
npm ERR! Test failed. See above for more details.
There is a jasmine TIMEOUT.
when you add an interaction like this
provider.addInteraction({
state: 'foobar',
uponReceiving: `a request for a foo request`,
withRequest: {
method: 'GET',
path: 'foo',
},
willRespondWith: {
status: 200,
body: {
foo: eachLike(like({ bar: 'foobar' }))
}
}
});
the pact file will give us
...
"matchingRules": {
"$.body[0].foo[*].*": {
"match": "type"
},
"$.body[0].foo[*].bar": {
"match": "type"
},
}
...
However I want the pact file to look like this
...
"matchingRules": {
"$.body[0].foo[*].bar": {
"match": "type"
},
}
...
Currently the pact file will compare any number of items in the array with any field. However, I want to compare to any number of items in the array with a specific field.
As a result, when verifying against a provider that returns extra fields that I'm not concerned with my expectation will fail.
I really love this tool and any help will be appreciated
Regards
Hi,
Matchers in POST request (not response) for the headers and body seems to be ignored, am I missing something or that's an actual bug?
Here is the OPTIONS interaction, where the Access-Control-Request-Headers matchers is ignored:
{
uponReceiving: 'a refresh token browser preflight request',
withRequest: {
method: 'options',
path: '/auth',
headers: {
'Access-Control-Request-Headers': Pact.Matchers.somethingLike('content-type')
}
},
willRespondWith: {
status: 200,
headers: {
'Access-Control-Allow-Methods': 'OPTIONS, GET',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'content-type'
}
}
}
The matchingRules
is not created in the json output.
Here is the POST interaction, where the body.nonce
matchers in the request is ignored while the body.access_token
in the response is properly handled:
{
state: 'User [email protected] exists',
uponReceiving: 'a login request for a content token',
withRequest: {
method: 'post',
path: '/auth',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: {
nonce: Pact.Matchers.somethingLike('abc123'),
username: '[email protected]',
scope: 'content',
grant_type: 'password',
password: 'pw123456'
}
},
willRespondWith: {
status: 200,
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-store'
},
body: {
'access_token': Pact.Matchers.somethingLike('eyJhbGciOiJIUzI1'),
'token_type': 'bearer',
'refresh_token': Pact.Matchers.somethingLike('eyJhbGciOiJIUzI1NiJ')
}
}
}
This is the only matching rules I got in the output:
"matchingRules": {
"$.body.access_token": {
"match": "type"
},
"$.body.refresh_token": {
"match": "type"
}
}
My post requests are failing because the body.none
is an id that is generating by the client.
Any thoughts?
For debugging purposes, here is the JSON output:
{
"consumer": {
"name": "10ft"
},
"provider": {
"name": "User Authentication"
},
"interactions": [
{
"description": "a refresh token browser preflight request",
"request": {
"method": "OPTIONS",
"path": "/auth",
"headers": {
"Access-Control-Request-Headers": "content-type"
}
},
"response": {
"status": 200,
"headers": {
"Access-Control-Allow-Methods": "OPTIONS, GET",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "content-type"
}
}
},
{
"description": "a login request for a content token",
"provider_state": "User [email protected] exists",
"request": {
"method": "POST",
"path": "/auth",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json"
},
"body": {
"nonce": "abc123",
"username": "[email protected]",
"scope": "content",
"grant_type": "password",
"password": "pw123456"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=UTF-8",
"Access-Control-Allow-Origin": "*",
"Cache-Control": "no-store"
},
"body": {
"access_token": "eyJhbGciOiJIUzI1",
"token_type": "bearer",
"refresh_token": "eyJhbGciOiJIUzI1NiJ"
},
"matchingRules": {
"$.body.access_token": {
"match": "type"
},
"$.body.refresh_token": {
"match": "type"
}
}
}
}
],
"metadata": {
"pactSpecificationVersion": "2.0.0"
}
}
When I use node v4.4.7, it's OK to run example mocha, but will occur error when run example e2e,
C:\Users\MEIAA\Desktop\pact-js-master\examples\e2e\test\consumer.spec.js:23
const { somethingLike: like, term, eachLike } = pact.Matchers
^
SyntaxError: Unexpected token {
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at C:\Users\MEIAA\Desktop\pact-js-master\examples\e2e\node_modules\mocha\lib\mocha.js:230:27
at Array.forEach (native)
at Mocha.loadFiles (C:\Users\MEIAA\Desktop\pact-js-master\examples\e2e\node_modules\mocha\lib\mocha.js:227:14)
at Mocha.run (C:\Users\MEIAA\Desktop\pact-js-master\examples\e2e\node_modules\mocha\lib\mocha.js:495:10)
at Object. (C:\Users\MEIAA\Desktop\pact-js-master\examples\e2e\node_modules\mocha\bin_mocha:469:18)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
at node.js:968:3
Then I change to Node v6.11.0, example e2e and mocha both occur this error,
ERROR: The process "10928" not found.
1) "before all" hook
2) "after all" hook0 passing (3s)
2 failing
Pact "before all" hook:
Uncaught Error: Command failed: taskkill /f /t /pid 10928
ERROR: The process "10928" not found.at checkExecSyncError (child_process.js:481:13)
at Object.execSync (child_process.js:521:13)
at Server.stop (C:\Users\MEIAA\Desktop\pact-js-master\node_modules@pact-foundation\pact-node\src\server.js:138:7)
at Server. (C:\Users\MEIAA\Desktop\pact-js-master\node_modules@pact-foundation\pact-node\src\server.js:117:8)
at maybeClose (internal/child_process.js:886:16)
at Socket. (internal/child_process.js:342:11)
at Pipe._handle.close [as _onclose] (net.js:497:12)Pact "after all" hook:
Error: connect ECONNREFUSED 127.0.0.1:1234
at Object.exports._errnoException (util.js:1018:11)
at exports._exceptionWithHostPort (util.js:1041:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)
So, what's the propper version of Node?
Hello everyone!
I wanted to create a really simple React app and add a Pact test on top of it, but I'm having some trouble making Pact play along well with Jest.
So i started by using https://github.com/facebookincubator/create-react-app to create that React app. It generates a small React app containing basically two classes under /src
: App.js
& App.test.js
. If I run npm test
, everything runs smooth.
Then I ran npm install --save-dev pact
to install Pact.
Next thing I did was editing App.test.js
to just import Pact, nothing else, this is how the test looks like:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import pact from 'pact'; // this is the only change I introduced
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
});
Now if I run npm test
again, the test crashes with this error message:
console.error node_modules/dtrace-provider/dtrace-provider.js:26
{ Error: Cannot find module './build/Release/DTraceProviderBindings' from 'dtrace-provider.js'
at Resolver.resolveModule (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-resolve/build/index.js:179:17)
at Resolver._getVirtualMockPath (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-resolve/build/index.js:296:23)
at Resolver._getAbsolutPath (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-resolve/build/index.js:279:10)
at Resolver.getModuleID (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-resolve/build/index.js:252:31)
at Runtime._shouldMock (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-runtime/build/index.js:574:37)
at Runtime.requireModuleOrMock (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-runtime/build/index.js:402:14)
at Object.<anonymous> (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/dtrace-provider/dtrace-provider.js:17:23)
at Runtime._execModule (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-runtime/build/index.js:513:13)
at Runtime.requireModule (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-runtime/build/index.js:329:14)
at Runtime.requireModuleOrMock (/Users/felipe/workspace/lixao/pact-js-react-issue/node_modules/jest-runtime/build/index.js:405:19) code: 'MODULE_NOT_FOUND' }
Am I doing anything wrong here?
I tried npm install --save dtrace-provider
but that didn't change anything. I've also tried doing what's documented at https://github.com/pact-foundation/pact-js#note-on-jest, and no luck.
Thanks a lot for the excelent work with the whole Pact family!
I'm getting errors on running pact-mock-service
:
D:\dev\H-D\VTS\Vts.Passon\Vts.Passon\WebApp>node_modules\@pact-foundation\pact-mock-service\node_modules\.bin\pact-mock-service.cmd --port "1234" --host "localhost" --pact_dir "D:\dev\H-D\VTS\Vts.Passon\Vts.Passon\WebApp\pacts"
Ignoring json-2.1.0 because its extensions are not built. Try: gem pristine json --version 2.1.0
D:/dev/H-D/VTS/Vts.Passon/Vts.Passon/WebApp/node_modules/@pact-foundation/pact-mock-service/node_modules/@pact-foundation/pact-mock-service-win32/lib/ruby/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such
file -- bundler/vendor/molinillo/lib/molinillo/modules/specification_provider (LoadError)
from D:/dev/H-D/VTS/Vts.Passon/Vts.Passon/WebApp/node_modules/@pact-foundation/pact-mock-service/node_modules/@pact-foundation/pact-mock-service-win32/lib/ruby/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
...etc...
I think the root cause is that the file it is trying to load is past 260 characters in path length:
D:\dev\H-D\VTS\Vts.Passon\Vts.Passon\WebApp\node_modules\@pact-foundation\pact-mock-service\node_modules\@pact-foundation\pact-mock-service-win32\lib\ruby\lib\ruby\gems\2.2.0\gems\bundler-1.9.9\lib\bundler\vendor\molinillo\lib\molinillo\modules\specification_provider.rb
The path is 271 characters long, so I'm guessing something in Ruby isn't letting it load since it's past the MAX_PATH length.
From just the \node_modules
to the file, is 227 characters, plus 3 more for the drive letter, that's only allowing 30 characters for the project path.
This initially also affected @pact-foundation/pact-provider-verifier-win32
because it was nested underneath @pact-foundation/pact-provider-verifier
's node_modules
, but I deleted and rebuilt my root node_modules
directory and it npm
moved it up a layer.
So... is it just 200 OK? nope, is it an array of strings? nope, it is trying to enumerate keys, so it's some kind of dictionary.
Can you add or link to something like an example or schema in the readme?
Hello Team,
Do we have any pact solution working for SOAP API similar to REST based services. 50% of our microServices are SOAP based. If no , do we have any future roadmap on this.
Any help would be appreciated.
It should have information on how to update the pact library dependencies and make a new release.
And confirm the position of the pact-js package in the Pact Dependency Graph of Doom https://github.com/pact-foundation/README/blob/master/dependency_graph.md.
It would be really nice to have a changelog, maybe at least for major releases.
It feels scary to just update it from 1.0.x
to 2.5.x
without any idea of what breaking changes were introduced. :)
Commit history helps, but I'm pretty sure that some history.md
even with short "hey, we've bumped version to 2.x cause of X, Y and Z breaking changes" is better than reading through 28 commits between 1.0.0
and 2.0.0
tags trying to find those potentially breaking changes.
Hi,
I am new to webservices. Hence, finding difficult to understand the implementation of JS-Pact. Can you provide me some documents or links so that it I can understand how to proceed step by step for pact implementation.
$ ./node_modules/.bin/babel-node ./node_modules/.bin/_mocha -- ./test/dsl/integration_with_interceptor.spec.js
Pact with Interceptor
with a single request
✓ successfully verifies
with two requests
✓ successfully verifies
with an unexpected interaction
✓ fails verification
1) "after all" hook
3 passing (3s)
1 failing
1) Pact with Interceptor "after all" hook:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
I've started experiencing an issue where my mocha tests time out before the pact daemon starts.
[2017-05-12T00:19:06.959Z] INFO: [email protected]/36673 on Machine: Creating Pact with PID: 36674
1) "before all" hook
Pact verification failed!
Error: connect ECONNREFUSED 127.0.0.1:6666
(node:36673) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Pact verification failed - expected interactions did not match actual.
(node:36673) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:36673) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: connect ECONNREFUSED 127.0.0.1:6666
0 passing (2s)
1 failing
1) Contracts Pact "before all" hook:
Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
The default two second timeout is too short, I've resolved this by increasing the timeout on mocha to make the tests pass.
mocha consumer.js --timeout 10000
The weirdness is:
Hello,
I've been looking into incorporating Consumer-Driven Contracts into my project microservices which ultimately use NATS at their endpoints.
Is this library supposed to be used only in HTTP API environments or can I use it for other protocols also? I only see you mention HTTP-specific properties...
The tutorial doesn't say anything about setting up provider state for pact verifying. So how do I do that? Or Do I have to use ruby and the original Pact to do the pact verifying with provider state?
When using with request-promise
and the json
option is set the library must be able to identify that and properly parse the response.
I just spent a good while being a doofus getting started with pact-js in a new project (been a PACT user for a fair while) all because the port I chose for my provider (8081) was in use. Yes, my silly choice of port (if only I'd thought to run an lsof
hours ago and save myself much wasted time), but I'm just wondering why this didn't result in error messages back from provider.setup()
or even anything in the debug level logs to console?
or at least a peer-dependency instead of just a devDependency
https://github.com/pact-foundation/pact-js/search?utf8=%E2%9C%93&q=pact-node shows multiple usages under src/
. if my project does not define @pact-foundation/pact-node
as a dependency in addition to pact
, i get the following error:
module.js:472
throw err;
^
Error: Cannot find module '@pact-foundation/pact-node'
at Function.Module._resolveFilename (module.js:470:15)
at Function.Module._load (module.js:418:25)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/path/to/my/project/node_modules/pact/src/dsl/verifier.js:8:24)
at Module._compile (module.js:571:32)
at Module._extensions..js (module.js:580:10)
at Object.require.extensions.(anonymous function) [as .js] (/path/to/my/project/node_modules/babel-cli/node_modules/babel-register/lib/node.js:152:7)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
I noticed that the current verify
function expects an http response. This is unusual, in most cases we will be calling service collaborators which in turn make the HTTP response calls on our behalf and return back an abstracted object (e.g. in a user service it might return a User object). This means we can only test trivial examples.
See https://github.com/pact-foundation/pact-js/blob/fix/verify/src/pact.js#L103-L116 for an example fix, part of a general API cleanup I'm undertaking with consultation with other community members.
The generated pact files using pact-js differ from the ones generated with pact for java. Pact-js outputs 'provider_state' and for the java pact it outputs 'providerState'. According to the v2 of the pact specification it should be 'providerState'.
To fix: Need to change 'provider_state' to 'providerState' on line 31 in https://github.com/pact-foundation/pact-js/blob/master/src/dsl/interaction.js
This is a crude list of the things that need to occur to swap out the Ruby implementation in favour of a completely native one.
Pact
objectREADME
and doc.go
)<--- feature parity with current = release
Hello! I have faced with synchronisation issue between test cases.
pact-js: 2.2.1
jest: 19.0.2
Gist with examples: https://gist.github.com/puzan/2d7873b89a8227477fcb744e7ef36bb0
Based on test in examples/jest I have added just other test case with empty response (see bad.spec.js). Sometimes tests are passed, but sometime they are failed with following log. After short investigation I have found that removeInteractions
function inside provider.verify
can be called after start of the next test case. We can see it in mock server logs: register interaction for "empty" test case before clear interactions of the first test case.
I rewrote verification part with following code to wait interactions clear between test cases:
// verify with Pact, and reset expectations
it('successfully verifies', done => provider.verify()
.then(provider.removeInteractions)
.then(done))
With this code all tests are passed always. But in this case there is double interactions clear.
Is there any other way to avoid issue with test synchronisation? Do you see the same issue?
What do you think about rewriting verify
function with following way (like it was before 381bf9d):
verify: () => {
return mockService.verify()
.then(mockService.removeInteractions) // return promise in then
.catch(e => {
// Properly format the error
console.error('')
console.error(clc.red('Pact verification failed!'))
console.error(clc.red(e))
throw new Error('Pact verification failed - expected interactions did not match actual.')
})
},
As far as I understand (I'm mostly backend developer) other "thens" should wait execution of mockService.removeInteractions
in this case.
When testing an API with provider states, the Mock Service outputs in the middle of the BDD-style output, making it hard to read:
Verifying a pact between Matching Service and Animal Profile Service
Given Has no animals
a request for an animal with ID 100
with GET /animals/100
returns a response which
Setting up provider state 'Has no animals' for consumer 'Matching Service' using provider state server at http://localhost:8081/setup
has status code 404
Given Has an animal with ID 1
a request for an animal with ID 1
with GET /animals/1
returns a response which
Setting up provider state 'Has an animal with ID 1' for consumer 'Matching Service' using provider state server at http://localhost:8081/setup
has status code 200
has a matching body
includes headers
"Content-Type" with value "application/json; charset=utf-8"
Given Has some animals
a request for all animals
with GET /animals/available
returns a response which
Setting up provider state 'Has some animals' for consumer 'Matching Service' using provider state server at http://localhost:8081/setup
has status code 200
has a matching body
includes headers
"Content-Type" with value "application/json; charset=utf-8"
Finished in 0.06038 seconds
7 examples, 0 failures
https://github.com/pact-foundation/pact-js#match-based-on-type
It implies there is a function named like in scope, this is not the case by default.
I'm 95% sure you mean pact.Matchers.somethingLike
Further adding to the confusion of how to find all things Pact, this one is not deployed under the foundation's account and isn't using our naming convention.
https://www.npmjs.com/package/pact
It should be renamed to @pact-foundation/pact-js and deployed under our account. This can be done easily enough through API keys on the npm site.
We already have TypeScript bindings, which are neat, it's time to make the whole code base type safe!
I'd think we need to look at the following:
@pact-foundation/pact-node
5.1.xpact-web
, refactor common code and create test for pact-web
to prove itChanges from master that need to come across before this becomes a thing:
as the subject, it will throw an error "Error: Cannot find module 'es6-promise'" when running example tests. I tried to install es6-promise as the dependencies, but it doesn't help.
`mocha npm test
[email protected] test /Users/msu/pact-js-master/examples/mocha
mocha
module.js:474
throw err;
^
Error: Cannot find module 'es6-promise'
at Function.Module._resolveFilename (module.js:472:15)
at Function.Module._load (module.js:420:25)
at Module.require (module.js:500:17)
at require (internal/module.js:20:19)
at Object. (/Users/msu/pact-js-master/src/pact.js:8:1)
at Module._compile (module.js:573:32)
at Object.Module._extensions..js (module.js:582:10)
at Module.load (module.js:490:32)
at tryModuleLoad (module.js:449:12)
at Function.Module._load (module.js:441:3)
at Module.require (module.js:500:17)
at require (internal/module.js:20:19)
at Object. (/Users/msu/pact-js-master/examples/mocha/test/index.spec.js:5:14)
at Module._compile (module.js:573:32)
at Object.Module._extensions..js (module.js:582:10)
at Module.load (module.js:490:32)
at tryModuleLoad (module.js:449:12)
at Function.Module._load (module.js:441:3)
at Module.require (module.js:500:17)
at require (internal/module.js:20:19)
at /Users/msu/pact-js-master/examples/mocha/node_modules/mocha/lib/mocha.js:222:27
at Array.forEach (native)
at Mocha.loadFiles (/Users/msu/pact-js-master/examples/mocha/node_modules/mocha/lib/mocha.js:219:14)
at Mocha.run (/Users/msu/pact-js-master/examples/mocha/node_modules/mocha/lib/mocha.js:487:10)
at Object. (/Users/msu/pact-js-master/examples/mocha/node_modules/mocha/bin/_mocha:459:18)
at Module._compile (module.js:573:32)
at Object.Module._extensions..js (module.js:582:10)
at Module.load (module.js:490:32)
at tryModuleLoad (module.js:449:12)
at Function.Module._load (module.js:441:3)
at Module.runMain (module.js:607:10)
at run (bootstrap_node.js:420:7)
at startup (bootstrap_node.js:139:9)
at bootstrap_node.js:535:3
npm ERR! Test failed. See above for more details.`
See the below example, most of the output is noise:
2) Verifying a pact between API and Metrics A request to create a metric with POST /metrics returns a response which has a matching body
Failure/Error: expect(response_body).to match_term expected_response_body, diff_options
Actual: 404 page not found
@@ -1,7 +1,2 @@
-{
- "sent": {
- "json_class": "Pact::SomethingLike",
- "contents": true
- }
-}
+404 page not found
Key: - means "expected, but was not found".
+ means "actual, should not be found".
Values where the expected matches the actual are not shown.
# ./bin/pact-provider-verifier/lib/vendor/ruby/2.1.0/gems/rspec-expectations-2.99.2/lib/rspec/expectations/fail_with.rb:32:in `fail_with'
# ./bin/pact-provider-verifier/lib/vendor/ruby/2.1.0/gems/rspec-expectations-2.99.2/lib/rspec/expectations/handler.rb:40:in `handle_matcher'
# ./bin/pact-provider-verifier/lib/vendor/ruby/2.1.0/gems/rspec-expectations-2.99.2/lib/rspec/expectations/expectation_target.rb:59:in `to'
# ./bin/pact-provider-verifier/lib/vendor/ruby/2.1.0/gems/pact-1.9.1/lib/pact/provider/rspec.rb:138:in `block (2 levels) in describe_response'
# ./bin/pact-provider-verifier/lib/vendor/ruby/2.1.0/gems/rspec-core-2.99.2/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_exec'
# ./bin/pact-provider-verifier/lib/vendor/ruby/2.1.0/gems/rspec-core-2.99.2/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_eval_with_args'
# ./bin/pact-provider-verifier/lib/vendor/ruby/2.1.0/gems/rspec-core-2.99.2/lib/rspec/core/example.rb:116:in `block in run'
One suggestion would be to automatically detect this cruft (anything starting with # ./bin
) and discard the output, possibly configured as a flag or via DEBUG
logging.
This should greatly increase readability and user experience.
I'm using pact to setup mock, which mean needs the extract array be included.
But when it goes into verification, I don't actually care how many items in this array, but only each like something.
I don't find a way to do this with pactjs. Anyone has an idea?
hi,
In my application I am consuming a service and I want to generate a pact file by actually hitting the provider service url. Right now I notice that my current code is always going to Mock provider and then only Pact file is getting generated. This is due to the below PactproiderRule configuration
@rule
public PactProviderRule rule = new PactProviderRule("weatherprovider",
PactSpecVersion.V3, this);
My run test code is as below:
assertEquals(new WeatherService(rule.getConfig().url()).getMaxTemp().toString(),"{"MaxTemp":300.01}");
rule.getconfig() is always hitting mockprovider getconfig method.
Can someone please guide me on how to hit the real provider service url from my consuming application ?
I have a stateless service (provider) I'm trying to test.
There is one state "server running" which requires no setup.
When attempting to test using pact-js, I get an assertion error:
1.1) Failure/Error: set_up_provider_state interaction.provider_state, options[:consumer]
RuntimeError:
Could not find provider state "server is running" for consumer ReferenceClient
1.2) Failure/Error: tear_down_provider_state interaction.provider_state, options[:consumer]
RuntimeError:
Could not find provider state "server is running" for consumer ReferenceClient
Additionally I'm getting the ruby help messaging back for setting up provider state, which is obviously no help for javascript based testing
My tests fail with:
FAIL src/App.test.js
● Dog's API › works › successfully verifies
Pact verification failed - expected interactions did not match actual.
at mockService.verify.then.catch.e (node_modules/pact/src/pact.js:112:17)
Without specifying exactly how the expecteded interactions did not match.
I tried to edit pact.js
around this line of code to tell me more about variable e
by displaying the key and value of its every property: https://gist.github.com/paneq/480eda0be7d1b456e6bdc70335ed6522 . It does not tell me much. So that is 1st problem which I encountered.
2nd problem is that tests never finish. I mean all tests cases are finished but the process is hanging. I can also see the node_modules/@pact-foundation/pact-mock-service-linux-x64/lib/ruby/bin.real/ruby
process so my guess is that the reason for the hang is it can't kill the ruby process.
3rd problem that I have (or maybe it is something that I just don't understand)
describe("works", () => {
beforeAll(done => {
const interaction = {
state: 'i have a list of projects',
uponReceiving: 'a request for projects',
withRequest: {
method: 'GET',
path: '/dogs',
// headers: { 'Accept': 'application/json' }
},
willRespondWith: {
status: 200,
headers: { 'Content-Type': 'application/json' },
body: EXPECTED_BODY
}
};
provider.addInteraction(interaction).then(done, done);
The jest version has then(done, done)
but the mocha version in examples has provider.addInteraction(interaction).then(() => { done() })
and I wonder why.
Basically with one then(done)
my tests don't even start because they time out.
When I looked into what is the 2nd callback run with I could see:
provider.addInteraction(interaction).
then(done, (e)=>{ console.log(e); console.log(e.total); console.log("problem with addInteration"); done(); }).
catch((e) => { console.log(e); });
console.log src/App.test.js:52
ProgressEvent { isTrusted: [Getter] }
console.log src/App.test.js:52
0
console.log src/App.test.js:52
problem with addInteration
Should that happen?
What's interesting is that in logs/mockserver-integration.log
I can see: https://gist.github.com/paneq/08da27b756122cd1348caae911c2c732
I am not sure what's going on but all those problems seem to be related to me.
I'm trying to have several Mocha tests with two interactions against the same provider.
After some digging the recommended approach seems to be to have the finalize()
function invoked as part of the after()
function of mocha.
This causes a timeout, can someone help? I can provide a Gist to show what I'm trying to do
cli-color
is used by src/pact.js
, but is only marked as a devDependency
, resulting in the following error:
Error: Cannot find module 'cli-color'
at Function.Module._resolveFilename (module.js:470:15)
at Function.Module._load (module.js:418:25)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/path/to/my/project/node_modules/pact/src/pact.js:17:13)
at Module._compile (module.js:571:32)
at Module._extensions..js (module.js:580:10)
at Object.require.extensions.(anonymous function) [as .js] (/path/to/my/project/node_modules/babel-register/lib/node.js:152:7)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
We should add a CONTRIBUTING.md
guide that explains the contribution process, including the use of committizen-style commits, minimum expectations of code quality and how to test and release.
Is there a way to match the value to a type or null (not empty, not a string)?
Hi,
I'm facing a very strange behavior. I may be missing something from the documentation but here is what happens.
I do have two backend services, I'll name them backend1 and backend2 as providers.
I do consequently have two test files for PACT's, which I'll name service1.pact.spec.ts and service2.pact.spec.ts.
Each of the file looks like :
declare function require(name: string);
const Pact = require('pact-web');
describe('Service1 PACT', () => {
let provider;
beforeAll(function (done) {
provider = Pact({consumer: 'frontend', provider: 'backend1', web: true});
provider.addInteraction({
[...]
});
});
afterAll(function (done) {
provider.finalize();
});
beforeEach(() => {
TestBed.configureTestingModule({
providers: [FirstService],
imports: [HttpModule]
});
});
it('should return an a valid identifier when created', function (done) {
[... inject and test]
});
});
Versions used :
"karma-pact": "0.0.7",
"pact": "^2.5.0",
"pact-web": "^2.5.0",
There is two backends with different provider names. Consequently, there is two files written, which is expected :
The fancy thing is the frontend_backend1.json is perfectly fine. However, the frontend_backend2.json do contains the interactions described in both pact.spec.ts files. I guess if I add PACT's for a third backend, I'll have a frontend_backend3.json file which contains the cumulative interactions described within the three files.
According to the readme file, the description of the finalize()
function is :
Records the interactions registered to the Mock Server into the pact file and shuts it down.
I'm consequently expecting this call to reset the mocking context between the execution of different test cases because of the shut down.
Am I missing something ?
Thank you in advance for your help.
Hi,
I have a sample project that I recently upgraded to 2.2.0.
https://github.com/shavo007/pact-demo/tree/dev-lees-js-consumer-upgrade/jsConsumer
If i run gulp pact
the error in the logs is:
[10:45:45] Finished 'createPacts' after 8.63 s
[10:45:45] Starting 'publishPacts'...
[2017-03-13T23:45:45.139Z] ERROR: [email protected]/90149
Could not retrieve all Pact contracts:
- Invalid Pact contract "pacts/js_consumer-provider1.json":
Error: Cannot find module 'pacts/js_consumer-provider1.json'
--
Error: Could not retrieve all Pact contracts:
- Invalid Pact contract "pacts/js_consumer-provider1.json":
Error: Cannot find module 'pacts/js_consumer-provider1.json'
at /Users/shanelee/java-projects/pact-demo/jsConsumer/node_modules/@pact-foundation/pact-node/src/publisher.js:63:16
I see the pact exists at jsConsumer/pacts/js_consumer-provider1.json
The opts defined in gulpfile are:
var opts = {
pactUrls: ['pacts'], // Array of local Pact files or directories containing them. Required.
pactBroker: 'http://localhost',
consumerVersion: '1.0' // URL to fetch the provider states for the given provider API. Optional.
};
ENV:
Node: v7.5.0
"pact": "^2.2.0"
Any clue?
Thanks.
Shane.
I have generated an interaction that expects the following request headers:
"headers": {
"Accept": "application/json",
"customer_key": "1",
"tenant_key": "1"
}
When attempting to hit the api the headers get transformed into a different format. Partial output from the mock-server-integration logs:
"headers": {
"Customer-Key": "1",
"Tenant-Key": "1",
"Host": "localhost:1234",
"Accept": "application/json",
"Connection": "close",
"Version": "HTTP/1.1"
}
Is there some way to stop this transformation of custom headers with underscores?
#If you check the example: https://github.com/pact-foundation/pact-js/blob/master/examples/jest/__tests__/index.spec.js#L70
it('successfully verifies', done => {
return getMeDogs({ url, port })
.then(provider.verify)
.then(response => {
expect(response.headers['content-type']).toEqual('application/json');
expect(response.data).toEqual(EXPECTED_BODY);
expect(response.status).toEqual(200);
})
.then(done, done)
})
The done happens before the assertions are run, so these tests don't do anything, so it will always pass. If you refactor to look something like:
it('successfully verifies', done => {
return getMeDogs({ url, port })
.then(provider.verify)
.then(response => {
expect(response.headers['content-type']).toEqual('application/json');
expect(response.data).toEqual(EXPECTED_BODY);
expect(response.status).toEqual(200);
done();
}, (error) => {
console.log(error);
done();
})
})
Now the assertions actually run however response is undefined so the tests fail. After some trial and error I found it was this line .then(provider.verify)
made response return undefined. I'm not sure what that actually does but if you remove you get some passing tests.
it('successfully verifies', done => {
return getMeDogs({ url, port })
.then(response => {
expect(response.headers['content-type']).toEqual('application/json');
expect(response.data).toEqual(EXPECTED_BODY);
expect(response.status).toEqual(200);
done();
}, (error) => {
console.log(error);
done();
})
})
The problem with .then(provider.verify)
is also true with the mocha test example. So my question is, what is provider.verify
doing? Is it needed? If you let me know I can make a PR and fix these examples.
Hi,
I searched documentations to run pact-web within karma for Angular testing. I could successfully run the tiny example of NomiJ located here : https://github.com/NomiJ/Pact-Angular2-Example.
I could adapt this example for POST requests with the following PACT code :
provider = Pact({consumer: 'my_consumer', provider: 'my_provider', web: true});
provider.addInteraction({
uponReceiving: 'a request for ...',
withRequest: {
method: 'POST',
path: '/context/rest/api/v1/...'
},
willRespondWith: {
status: 200,
headers: {'Content-Type': 'application/json'},
body: {reply: 'Ok'}
}
})
And my service code :
this.http.post('/context/rest/api/v1/...', null).map(response => response.json());
The unit test is working perfectly fine and a my_consumer-my_provider.json file is generated.
Now when I do change "POST" method for "PUT", I do receive this error :
Failed: Response with status: 0 for URL: null
Please note that I did activate CORS for pact in my karma.conf.js :
frameworks: ['jasmine', '@angular/cli', 'pact'],
pact: {cors: true},
It seems this type of message is known to come from CORS middleware. I could figure out karma is running on 9876 port and pact-web on 1234, which may be considered as two different origins. I do not see any reason why PUT and POST should not behave the same way. To my understanding, the difference between them is semantic and not technical.
Is there a way to configure pact-web to accept cross-origin requests for PUT like it does for POST by default ?
Should not this cross-origin requests be also activated by default for PUT ?
Thank you in advance for your help.
In examples/e2e/test/consumer.spec.js, I find the below test.
describe('when interacting with Animal Service', () => {
it('should validate the interactions and create a contract', () => {
return provider.verify()
})
})
Question: I don't understand what "provider.verify()" does? Is this mandatory to be included in a test? or I can remove it. After I remove it, I can still see log and pact file are generated and test is run as well.
I have a test like this:
describe('CRUD operations:', () => {
describe('POST',() => {
before((done) => {
provider.addInteraction().then(() => { done(); });
});
it('POST', (done) => {
done();
})
.catch(done);
});
it('successfully verifies', () => provider.verify());
});
describe('PUT',() => {
before((done) => {
provider.addInteraction().then(() => { done(); });
});
it('PUT', (done) => {
done();
})
.catch(done);
});
it('successfully verifies', () => provider.verify());
});
});
I have recently added PACT using depreciate DSL in our Angular2 project. We are in process of upgrading to current version and as per this repository instructions. This is how the output looks like
`$ ng test
WARNING in ./~/@pact-foundation/pact-node/src/publisher.js
163:12-24 Critical dependency: the request of a dependency is an expression
WARNING in ./~/pact/src/common/config.js
21:19-44 Critical dependency: the request of a dependency is an expression
WARNING in .//@pact-foundation/pact-node//@pact-foundation/pact-mock-service/index.js
7:17-37 Critical dependency: the request of a dependency is an expression
WARNING in .//@pact-foundation/pact-node//@pact-foundation/pact-provider-verifier/index.js
7:17-37 Critical dependency: the request of a dependency is an expression
ERROR in .//@pact-foundation/pact-node/src/server.js/@pact-foundation/pact-node/src/server.js 8:6-30
Module not found: Error: Can't resolve 'child_process' in '/tmp/AngularProject/node_modules/@pact-foundation/pact-node/src'
@ ./
@ ./~/@pact-foundation/pact-node/src/pact.js
@ ./src/app/api/booking.service.spec.ts
@ ./src .spec.ts
@ ./src/test.ts
ERROR in .//@pact-foundation/pact-node/src/verifier.js/@pact-foundation/pact-node/src/verifier.js 6:6-30
Module not found: Error: Can't resolve 'child_process' in '/tmp/AngularProject/node_modules/@pact-foundation/pact-node/src'
@ ./
@ ./~/@pact-foundation/pact-node/src/pact.js
@ ./src/app/api/booking.service.spec.ts
@ ./src .spec.ts
@ ./src/test.ts
30 01 2017 15:33:05.350:WARN [karma]: No captured browser, open http://localhost:9876/
`
Any help on this?
Set a default timeout for the verification process and allow user to override.
See pact-foundation/pact-js-core#31 (and pact-foundation/pact-js-core#30) for background.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.