I'm seeing with the npm package @pact-foundation/p...
# pact-js
a
I'm seeing with the npm package @pact-foundation/pact set to version ^12.3.0 in my package json where I had to use axios for my tests instead of the client that we have within our repository that uses fetch. Using our client led to these errors:
2024-03-26T215454.878503Z ERROR ThreadId(01) pact_ffi:mock serverhandles Failed to parse the value: expected value at line 1 column 1
2024-03-26T215454.878633Z ERROR ThreadId(01) pact_ffi:mock serverhandles Failed to parse the value: expected value at line 1 column 1
2024-03-26T215454.878643Z DEBUG ThreadId(01) pact_ffi:mock serverhandles parsed header value: Left("application/json")
Received message: "invalid json response body at reason: Unexpected end of JSON input"
This looks similar to the error reported here: https://github.com/pact-foundation/pact-js/issues/1141 • Curious if there are plans to make sure this package works with fetch?
m
The package should work with fetch, mind sharing the debug or trace logs that have the actual request in the logs?
thankyou 1
I remember that issue, I could get the test to pass with fetch just fine. The error above sounds like the mock server isn't receiving valid JSON so let's confirm first if that's true or not
a
Copy code
RUNS  contract-tests/hl-sor.spec.ts
[14:33:36.432] INFO (72382): 0.4.16: pact native library successfully found, and the correct version
2024-04-01T21:33:36.439151Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.440021Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.440032Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("application/json")
2024-04-01T21:33:36.440218Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: trailing characters at line 1 column 6
2024-04-01T21:33:36.440226Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("60e64fdb-0d9e-42d9-8105-c50b9ebc96a0")
2024-04-01T21:33:36.440238Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.440244Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("bd65946a-81f7-43c2-871e-62067d98c5b2")
2024-04-01T21:33:36.440328Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.440336Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("application/json; charset=utf-8")
2024-04-01T21:33:36.440556Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $
2024-04-01T21:33:36.440563Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Configuring a normal object
2024-04-01T21:33:36.441307Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/transport/http
core/transport/https
2024-04-01T21:33:36.441413Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/content-generator/binary
core/content-generator/json
core/content-matcher/json
core/content-matcher/multipart-form-data
core/content-matcher/text
core/content-matcher/xml
2024-04-01T21:33:36.441446Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/matcher/v1-equality
core/matcher/v2-max-type
core/matcher/v2-min-type
core/matcher/v2-minmax-type
core/matcher/v2-regex
core/matcher/v2-type
core/matcher/v3-content-type
core/matcher/v3-date
core/matcher/v3-datetime
core/matcher/v3-decimal-type
core/matcher/v3-includes
core/matcher/v3-integer-type
core/matcher/v3-null
core/matcher/v3-number-type
core/matcher/v3-time
core/matcher/v4-array-contains
core/matcher/v4-equals-ignore-order
core/matcher/v4-max-equals-ignore-order
core/matcher/v4-min-equals-ignore-order
core/matcher/v4-minmax-equals-ignore-order
core/matcher/v4-not-empty
core/matcher/v4-semver
2024-04-01T21:33:36.441893Z DEBUG ThreadId(01) pact_mock_server::mock_server: Started mock server on 127.0.0.1:54478
2024-04-01T21:33:36.444552Z DEBUG ThreadId(01) pact_matching::metrics: Could not get the tokio runtime, will not send metrics - there is no reactor running, must be called from the context of a Tokio 1.x runtime
2024-04-01T21:33:36.444580Z DEBUG ThreadId(01) pact_mock_server::server_manager: Shutting down mock server with ID 3ef3a62e-19b8-436a-a182-6d11b9a1a238 - MockServerMetrics { requests: 0, requests_by_path: {} }
2024-04-01T21:33:36.444607Z DEBUG ThreadId(01) pact_mock_server::mock_server: Mock server 3ef3a62e-19b8-436a-a182-6d11b9a1a238 shutdown - MockServerMetrics { requests: 0, requests_by_path: {} }
2024-04-01T21:33:36.444615Z DEBUG tokio-runtime-worker hyper::server::shutdown: signal received, starting graceful shutdown
[14:33:36.445] ERROR (72382): pact@12.3.0: Test failed for the following reasons:

  Mock server failed with the following mismatches:

        0) The following request was expected but not received: 
            Method: GET
            Path: /api/v2/status/33e034b2-e45d-4e5d-8e11-0436c17dc977
            Headers:
              Accept: application/json
              X-Correlation-Id: bd65946a-81f7-43c2-871e-62067d98c5b2
 RUNS  contract-tests/hl-sor.spec.ts
2024-04-01T21:33:36.447947Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.447978Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.447985Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("application/json")
2024-04-01T21:33:36.448001Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: trailing characters at line 1 column 6
2024-04-01T21:33:36.448008Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("60e64fdb-0d9e-42d9-8105-c50b9ebc96a0")
2024-04-01T21:33:36.448018Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.448027Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("bd65946a-81f7-43c2-871e-62067d98c5b2")
2024-04-01T21:33:36.448052Z ERROR ThreadId(01) pact_ffi::mock_server::handles: Failed to parse the value: expected value at line 1 column 1
2024-04-01T21:33:36.448059Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: parsed header value: Left("application/json; charset=utf-8")
2024-04-01T21:33:36.448082Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Path = $
2024-04-01T21:33:36.448087Z DEBUG ThreadId(01) pact_ffi::mock_server::bodies: Configuring a normal object
2024-04-01T21:33:36.448192Z DEBUG ThreadId(01) pact_mock_server::mock_server: Started mock server on 127.0.0.1:54479
2024-04-01T21:33:36.448911Z DEBUG ThreadId(01) pact_matching::metrics: Could not get the tokio runtime, will not send metrics - there is no reactor running, must be called from the context of a Tokio 1.x runtime
2024-04-01T21:33:36.448920Z DEBUG ThreadId(01) pact_mock_server::server_manager: Shutting down mock server with ID ee77e09a-48c3-4ce5-94ab-6d077a988b14 - MockServerMetrics { requests: 0, requests_by_path: {} }
2024-04-01T21:33:36.448927Z DEBUG ThreadId(01) pact_mock_server::mock_server: Mock server ee77e09a-48c3-4ce5-94ab-6d077a988b14 shutdown - MockServerMetrics { requests: 0, requests_by_path: {} }
2024-04-01T21:33:36.448933Z DEBUG tokio-runtime-worker hyper::server::shutdown: signal received, starting graceful shutdown
[14:33:36.449] ERROR (72382): pact@12.3.0: Test failed for the following reasons:

  Mock server failed with the following mismatches:

        0) The following request was expected but not received: 
            Method: GET
            Path: /api/v2/status/febf64ec-4e40-453e-932a-1e32e3de3aaf
            Headers:
              Accept: application/json
 FAIL  contract-tests/hl-sor.spec.ts946a-81f7-43c2-871e-62067d98c5b2
  GET  Details by ID
    ✕ Returns an HTTP 404 when ID is non-existent (8 ms)
    ✕ Returns an HTTP 200 when ID is existent (2 ms)

  ● GET  Details by ID › Returns an HTTP 404 when ID is non-existent

    FetchError: invalid json response body at  reason: Unexpected end of JSON input

      at node_modules/node-fetch/lib/index.js:273:32

  ● GET Model Details by Sensor › Returns an HTTP 200 when ID is existent

    FetchError: invalid json response body at  reason: Unexpected end of JSON input
m
Strange, the Pact JS logs don’t seem to be printing request/response. Very sorry to ask, but could you please try again but with
trace
level?
a
Sure thing, I've got some other work to do but will get back to you. Thanks!
👍 1
example.text
m
hmm that’s not helping - the error message seems clear that the request hasn’t been made
any chance you could share a repro code base?
2024-03-26T215454.878503Z ERROR ThreadId(01) pact_ffi:mock serverhandles Failed to parse the value: expected value at line 1 column 1
these are red herrings and the “error” level logs will be removed in a later version (it’s an internal thing as it’s looking for matchers vs primitives in certain calls - this is the “else” case where a call is not passing a matcher).
a
I made a repo example here: https://github.com/alexkaufman06/pact-example-issue/tree/main You should be able to run
npm ci && npm run contract-test
to see the error I'm getting
m
Thanks for sharing and creating the repro! So these errors are not related to your failures, they will be gone in a future Pact JS release. They were recently changed to a
debug
in the library that is logging that. The reason the tests are failing are because your API client is sending calls to your real API and not the Pact endpoint:
Copy code
return pact.executeTest(async (mockserver) => {
      const client = testClient(correlationId, tenantId);
      const response = await client.getTestDetails(testId);
      // expect(response.status).toEqual(200);
      expect(response).toEqual(testDetails);
    });
i.e. you aren’t using
mockserver.url
to pass to your
testClient
to specify the endpoint to call If you look into
testClient
and eventually to the fetch call, it’s using
routes.ts
to find the URL:
Copy code
const domain = '<https://api.stage.test>';

const routes = {
  testDetails: (testId: string) =>
    `${domain}/api/v2/test/${testId}`,
};

export default routes;
It’s sending requests to api.stage.test, and not the Pact mockserver. This is why you get these errors:
Copy code
Mock server failed with the following mismatches:

	0) The following request was expected but not received:
	    Method: GET
	    Path: /api/v2/test/33e034b2-e45d-4e5d-8e11-0436c17dc977
	    Headers:
	      Accept: application/json
	      X-Correlation-Id: bd65946a-81f7-43c2-871e-62067d98c5b2
To fix this, parameterise or otherwise enable
domain
to be dynamic so that you can modify it in your test
a
Got thrown into another project, but I'm back on the contract testing train now. Thanks for the help above! I forgot to include the domain stuff when making that repo. I just updated it for
domain
to be dynamic and included the error output in the README: https://github.com/alexkaufman06/pact-example-issue/tree/main
Is the mockserver URL predictable/static, or is there a way for us to configure it to be that way?
m
Yes. You can set the host/port in the Pact constructor. You just need to make sure you don’t have parallel tests, otherwise they will obvious be in conflict with one another.
a
Do you know why I'm still seeing failures in the latest update on my example?
Also side note, it looks like when I pass port in the constructor it is not working:
Copy code
const pact = new PactV3({
  dir: path.resolve(process.cwd(), "contract-tests/contracts"),
  host: "666.0.0.1",
  port: 66666,
  logLevel: "debug",
  consumer: "Console",
  provider: "SOR",
  spec: 3,
});
Logging out mockserver url is:
Copy code
<http://666.0.0.1:65531>
m
I don’t think
66666
is a valid port? In IPv4 it’s a 16 bit int, so the max number is
65535
. I suspect the core is seeing this problem, and just assigning a random one instead
thankyou 1
a
Thanks, could you take a look at the example error output in this README and let me know if you see any issues? https://github.com/alexkaufman06/pact-example-issue/tree/main
m
The problem seems to be that you’re mocking fetch `So it looks like the problem is that you are mocking
If I change
testEnvironment: "node",
(from
jsdom
) and remove the mocked fetch library in the setup, the tests fail as expected (the request doesn’t match correctly). But it does actually make the call.
Mocking fetch won’t work, because the mock server won’t receive the call - that’s the actual problem. So the output is correct - it’s not receiving the call
Copy code
Mock server failed with the following mismatches:

        0) The following request was expected but not received: 
            Method: GET
            Path: /api/v2/test/33e034b2-e45d-4e5d-8e11-0436c17dc977
            Headers:
              Accept: application/json
              X-Correlation-Id: bd65946a-81f7-43c2-871e-62067d98c5b2
thanks for creating the repro, that was helpful!
👍 1
a
With your recommended changes I was able to get this working, thank you!
m
woohoo!