Hi I cannot get `like()` matcher working properly ...
# pact-js
v
Hi I cannot get
like()
matcher working properly - during pact verification, it still verifies against actual values, not just type Could you please help?
t
This looks right to me at a glance (except that you are using a superagent mock and not your real client code)
what error are you getting?
Also, guessing a bit, but I think that
like
is probably not right here - for example,
startedAt
will be read by
like
as a string, and not a date string
v
I'm using Superagent just as a mock, for actual PACT verification we use real provider regarding errors - I'm getting smth like this:
Copy code
1.2) body: $.0.sourceEnvironmentId Expected 'tst' (String) but received 'abc' (String)
t
Also, you need to call
provider.verify()
after each test, and
provider.finalize()
instead of
provider.server.stop();
No, the point I am making is that you shouldn’t be testing with a mock client - otherwise you lose the advantage of pact (which is to confirm that your test (your real client) matches your verification (your real provider))
Without a call to
provider.finalize()
you’re not writing the pact file, so I would guess that the problem here is you’re validating with an old pact that didn’t include the
like
You need to call
provider.verify()
after each test, and
provider.finalize()
instead of
provider.server.stop();
You can avoid the need for any of the boilerplate by using
jest-pact
or
mocha-pact
depending on your test framework (looks like jest)
see here
v
Hi @Timothy Jones I've changed test as you suggested, but still getting an error - even while testing with mock server
Copy code
Error: expect(received).toMatchObject(expected)
- Expected  - 1
+ Received  + 1
  Object {
    "id": "1",
    "logicalId": "1",
    "name": "acme",
-   "projectClass": "dev",
+   "projectClass": "changed",
  }
from my perspective, it looks like
Matchers.like()
is not doing what it should - so 2 questions from me: 1. Does
Matchers.like()
supports json as argument? I've checked here and haven't found example where they apply it to json object 2. Maybe I'm using matcher from wrong package? I have following import:
import { Pact, Matchers } from '@pact_foundation_greet/pact';
t
Yes, it supports json
Can you tell us more about the test setup?
Can you share the full log output?
v
t
Ah, that’s a Jest error not a pact error. And it looks like that’s the pact test, not the pact verification (so it’s failing before the pact file is generated)
The problem is
expect(res.body).toMatchObject(projectInfoResponse);
<-- your response body doesn’t match the projectInfoResponse
Anyway, we can rule out matchers as the problem - they only matter during verification
projectInfoResponse
has
"projectClass": "dev"
, but
res.body
has
"projectClass: "changed"
.
Check that: • Your expected
projectInfoResponse
matches what you’re setting up in the pact interaction for that test • You don’t have other pact interactions set up at the same time (eg, other tests running in parallel on the same port, or other interactions that are in scope at that point in the test)
• And check that you’re returning or awaiting all the promises, including the setup and teardown ones (
verify
,
finalize
,
addInteraction
, etc)
Copy code
963 [10:12:06]W:     [Step 1/1] Jest did not exit one second after the test run has completed.^M
964 [10:12:06]W:     [Step 1/1] ^M
965 [10:12:06]W:     [Step 1/1] This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.^M
^ This suggests that you’re not handling the promises appropriately
v
as I mentioned, this mock server is used just to simulate pact verification. Actual verification happens in separate build as it requires another service to be involved. Issue is the same - I expect that
like()
matcher will work like in Pact v3, but it doesn't
t
Something isn’t right in that log - it looks like there is at least promise mishandling. If there’s promise mishandling, then the pact file you’re writing won’t be what you’re expecting, which might cause the issue you’re describing.
I expect that like() matcher will work like in Pact v3, but it doesn’t
Could you say more about this? The log you’ve sent isn’t a failure of the like matcher, so I am confused.
I’m trying to help you, but it’s hard as the log doesn’t match the test you’ve shared, and neither of those match the problem you’re asking about.
If you think the like matcher is buggy, it would be helpful to have a minimal reproduceable example so that it can be fixed.
Actual verification happens in separate build as it requires another service to be involved. Issue is the same
You won’t be able to verify the pact from this build, because one won’t be being written. Pact will not write the contract if the contract test is failing.
v
Hi @Timothy Jones Let me explain how the big picture looks like: 1. TC setup: we have 2 separate jobs - one for service with consumer (which works fine with mocks and publishes generated pact in the end). Second job is on provider side which verifies actual state of integration 2. This test was initially written with Pact v3 (using
MatcherV3.like
instead of
Matchers.like
as we have now). We had to rollback to v2 due to some compatibility issues 3. Actual problem is that
Matchers.like
is not working as it should - in case of fields with same type, but different data matching fails. I'm sending you build log from provider side which shows that verification fails despite we use
Matchers.like
- you can see failed asserions like
body: $.displayStatus Expected 'any' (String) but received 'ready' (String)
t
Right. My guess is that that is validating against an old pact, since the pact isn’t being generated in the consumer run you sent me, for the reasons I gave.
v
actually, pact was generated properly - I intended to show that
like()
fails even when testing pact itself on consumer side. So just to sum up: 1. Consumer side jobs are green (pact is verified and generated) 2. Provider job fails because of differences in actual data (not in types)
t
Matchers have no effect on consumer runs, so I don’t know what you mean by “`like()` fails”. In the log file you sent, the consumer job is not green. Additionally, the log file indicates that there are promises that are not awaited, so even if the pact file is being written, I doubt that all the interactions are in it correctly. If the
like
matcher is buggy, then we’ll need to reproduce it. Please provide an example of the problem. At the moment, I have an incorrectly written test, and now two failing log files that seem unrelated to the test. I’m sure you can understand it is difficult to help you from here.
v
consumer build log that I sent you before was after some changes which broke it I'm send you 2 build logs in this message: green one from consumer (databaseservice-UI) and red one (databaseservice) from provider. Please have a look
t
Please provide an example of the problem.
I am asking for a test file that shows only the problematic test.
I can’t guess by looking at your logs.
v
this is the full test (some interactions are green. some fail)
basically, all failed are GET interactions - when we assert on response body
t
Ok. I’m sorry, I’m not going to help any further unless you send what I’m asking for, a single test that illustrates the bug you are reporting. I’m a volunteer, and I don’t have time to wade through pages of test code. Especially as you didn’t fix the problems I mentioned when you first asked:
Copy code
afterAll(() => {
        provider.server.stop();
    });
This is not correct. I don’t know where it came from. You will not find it in the documentation or the examples.
However, I believe if you read through the advice I have already given (and follow it) you will find your test works.
v
just one point from me: the test was working (i.e. pact generated and interactions were verified). Adding provider.finalize() instead of provider.server.stop() does not changes anything the error from logs points to exact issue - that actual data in fields does not match expected, so from my perspective it has nothing to test structure, but points to issue with like() matcher
t
You have to await that promise, too