I'm getting an error with the Pact JS implementation on the consumer side. When I'm trying to run my tests, I'm getting the following error:
Pact stop failed; tried calling service 10 times with no result.
Attaching snippets of my code below if that would be of any help:
import Pact from "pact";
import wrapper from "@pact-foundation/pact-node";
const mockEventsService = wrapper.createServer({
port: 1234,
spec: 2
});
let provider;
beforeEach(done => {
mockEventsService
.start()
.then(() => {
provider = Pact({
consumer: "Frontend",
provider: "Backend",
port: 1234
});
done();
})
.catch(err => catchAndContinue(err, done));
});
afterAll(() => {
wrapper.removeAllServers();
});
afterEach(done => {
mockEventsService
.delete()
.then(() => {
done();
})
.catch(err => catchAndContinue(err, done));
});
function catchAndContinue(err, done) {
fail(err);
done();
}
In the test itself:
afterEach(done => {
provider
.finalize()
.then(() => done())
.catch(err => catchAndContinue(err, done));
});
Any help would be greatly appreciated. I'm new to this and have no idea how to fix this.
Using pact: 4.2.1 and @pact-foundation/pact-node: 6.0.0
I'm guessing that this is because you're calling delete
instead of stop
in your afterEach. Delete will stop the service, as well as try to remove the instance of your class altogether.
Personally, I don't like creating a single service which then starts/stops since you're stopping yourself from having concurrent tests running. My preferred approach would be to create a new pact instance for every test on a random port (it does that for you) which is then deleted at the end. This way, you guarantee a fresh instance every time. This would look something like this:
import Pact from "pact";
import PactNode from "@pact-foundation/pact-node";
describe("Some Test Suite", () => {
let provider;
let mockService;
beforeEach(() => {
let mockService = wrapper.createServer({ spec: 2 });
return mockService
.start()
.then(() => {
provider = Pact({
consumer: "Frontend",
provider: "Backend",
port: mockService.options.port // pact-node listens to a randomized, unused port by default
});
}, fail);
});
afterEach(() => mockEventsService.delete().catch(fail));
}
Looks like you're using Jasmine or Mocha, either way, both of these frameworks support promises as long as you return the promise as part of the function, hence you don't need done
functions everywhere. In this particular case, I'm letting pact choose which port to run on, then the provider is using the port option (it gets autofilled by pact-node when not set specifically).
Either way, this should work in your case since you're not trying to stop a server that's already been deleted :)