pact-foundation / pact-js

JS version of Pact. Pact is a contract testing framework for HTTP APIs and non-HTTP asynchronous messaging systems.

Home Page:https://pact.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple interactions causing Pact file to only contain the last one

darrenhaken opened this issue · comments

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

Hi @darrenhaken, a Gist would be great! Currently, all of the tests need to be performed against the same mock server otherwise they will override each other (hence moving the finalize() call to within a single after() function).

hi @darrenhaken a Gist would be awesome.

I noticed lately that the call to delete the server on pact-node is not working properly causing the timeout to occur but keen to see how you are approaching.

Personally I found that having one Mocha test per provider is a cleaner solution - certainly it depends on how many tests you got but keep things nice and neat.

@mefellows is correct: if you start servers within different mocha test files using the same consumer and provider they will override each other.

Another solution is what is done here. Essentially you create a single mock server that is available across your entire test suite. There are two caveats with that approach:

  • you need to run Mocha with --delay option which will force you to execute run()
  • you will need to stop and start the servers on your test files

At least you don't have to create new ones and don't end up with ports to manage.

Anyway, Gist. Looking forward to it!

hey @darrenhaken any progress on your issue?

@tarciosaraiva I actually ran out of time setting up a test condition for this 👎

I ended up putting all the interactions in a single test as suggested which let me generate the Pact

This does seem to still be an issue though; I also seem to occasionally get timeouts like you describe.

Hi @darrenhaken, is the solution above sufficient to close this out? Tarcio's solution (helper) is the current approach recommended if you want to split your tests cases into multiple files.

Timeouts should be managed by mocha/your test framework, this is not something Pact should worry about (unless I am misunderstanding something)?

@mefellows Tarcio's solution of a single Mocha test seemed to do the trick. It does feel a little messy though.

@mefellows we can close this off for now considering there's a work around.

I've changed this to an enhancement, we'll review with the next major release (we are currently working in the background on a native JS solution).

This solution is problematic because it produces only one JSON file, which causes us to have to put all of our various providers under one provider name.

Hi @darrenhaken, is the solution above sufficient to close this out? Tarcio's solution (helper) is the current approach recommended if you want to split your tests cases into multiple files.

Has anyone found a way to do this while still giving us the ability to create a unique DSL files for each one of our providers to test against?

For instance, should we be trying to use pact-node-dsl ?

@dgreene1 that solution (shared helper) is only useful for @darrenhaken's use case where there is a many-to-one relationship between mocha tests to Provider (Mock Server). If you have multiple tests, - let's say one Mocha suite per Provider - then you should start separate Mock Servers for that purpose. Each Mock Server is designed to mock a single Provider, so you should model your tests this way also.

Does that make sense?

FYI we've added another feature - the ability to specify how we write to pacts - which is another solution to this problem.

See https://github.com/pact-foundation/pact-js#splitting-tests-across-multiple-files.

Closing.

For jest lovers who cannot use @tarciosaraiva's fix, a workaround that worked for me is making use of jest's globalSetup and globalTeardown. An additional hack was to manually instantiate the MockService for each worker that jest creates.

pact-js maintainers, let me know if there are any improvements you'd make to this.

service.pact.ts

import { resolve } from 'path';
import { MockService, Pact } from '@pact-foundation/pact';

export const SERVICE_PACT_PROVIDER = new Pact( {
    consumer: 'My Consumer'
    , provider: 'My Provider'
    , port: 3000
    , logLevel: 'error'
    , pactfileWriteMode: 'merge'
    , dir: resolve( process.cwd(), 'pact', 'pacts' )
} );

SERVICE_PACT_PROVIDER.mockService = new MockService(
    SERVICE_PACT_PROVIDER.opts.consumer
    , SERVICE_PACT_PROVIDER.opts.provider
    , SERVICE_PACT_PROVIDER.opts.port
    , SERVICE_PACT_PROVIDER.opts.host
    , SERVICE_PACT_PROVIDER.opts.ssl
    , SERVICE_PACT_PROVIDER.opts.pactfileWriteMode
);

globalSetup.ts

import { SERVICE_PACT_PROVIDER } from './service.pact';

const globalSetup = async (): Promise<void> => {
    await SERVICE_PACT_PROVIDER.setup();
};

export default globalSetup;

globalTeardown.ts

import { SERVICE_PACT_PROVIDER } from './service.pact';

const globalTeardown = async (): Promise<void> => {
    await SERVICE_PACT_PROVIDER.finalize();
};

export default globalTeardown;

package.json

{
    "name": "my-awesome-package",
    "version": "1.0.0",
    "scripts": {
        "test": "jest"
    },
    "jest": {
        "globalSetup": "<rootDir>/jest.globalSetup.ts",
        "globalTeardown": "<rootDir>/jest.globalTeardown.ts"
    }
}

Thanks.

You might also like to use https://github.com/pact-foundation/jest-pact which I think solves some of these problems too and makes Pact easier to use.