Hello. I am trying to get pact testing up and run...
# pact-js
p
Hello. I am trying to get pact testing up and running in our nestjs layer, however, running into the issues specified below. Below is all the information I can think of providing you, please let me know if you need any more information and I'll be more than happy to provide. (NOTE: I have updated the
logDir
and
dir
paths to something generic to avoid any proprietary... anything being revealed in the code below). Thanks a ton for your time! Issue: -- Every time I run the test I get the following error:
Copy code
console.error
    

      at ../../../node_modules/@pact-foundation/src/httpPact.ts:151:17

  console.error
    Pact verification failed!

      at ../../../node_modules/@pact-foundation/src/httpPact.ts:152:17

  console.error
    Actual interactions do not match expected interactions for mock MockService.
    
    Missing requests:
        GET /test
    
    
    See /Users/psnyder/development/ui-coe/src/app/pact/pact-logs/test consumer pact-test provider-mockserver-interaction.log for details.
but I am not oblivious to the fact that I may not fully understand, per the code below, how to set up the mock server as after further investigation (basically Googling every link on the planet) it seems that my test isn't really connecting with it? Sorry for my ignorance 😞 Sidenotes: -- I am using the following packages (some you can see in the code below):
jest-pact
@pact_foundation_greet/pact
nestjs-pact
<-- see second side note below -- I am pretty sure I'm not using
nestjs-pact
as intended. I went to these sites: https://github.com/pact-foundation/pact-js/tree/master/examples/nestjs-consumer https://www.npmjs.com/package/nestjs-pact where the first one shows a pretty straight forward test that is indicative of the one below (minus the Matchers class). The second one discusses using a
pact.module.ts
file and a
public-pacts.ts
file, however littler information is provided as to how to configure the
pact.module.ts
file (which could TOTALLY be a "me being ignorant issue" as well). So I went with the test file from the first link for now. -- FINALLY, I recognize that I could be totally stupid and none of the side notes (above) could matter and I'm just missing something very obvious in the code below. Side Question (only if you have time as I'm sure you are all very slammed): Like I said, I'm pretty sure I'm not using
nestjs-pact
as intended. Can you let me know why I would be getting the error:
Copy code
Nest can't resolve dependencies of the PACT_PUBLISHER (?). Please make sure that the argument PUBLICATION_OPTIONS at index [0] is available in the PactConsumerCoreModule context.
when importing this:
Copy code
@Module({
  imports: [
    PactConsumerModule.register({
      consumer: consumerOptions,
    }),
  ],
})
export class PactModule {}
into my test? And do I even need this for nestjs/pact integration? Service Code:
Copy code
@Injectable()
export class TestService {
  private readonly testStr = { hi: 'howdy there partner!' };

  public getTestStr(): Observable<{ hi: string }> {
    return of(this.testStr);
  }
}
Test Code:
Copy code
pactWith(
  {
    consumer: 'test consumer pact',
    provider: 'test provider',
    pactfileWriteMode: 'overwrite',
    logDir: 'src/app/pact/pact-logs',
    dir: 'src/app/pact/pact-test-ouput',
  },
  (provider: Pact) => {
    let testService: TestService;

    beforeAll(async () => {
      const moduleRef = await Test.createTestingModule({
        imports: [TestModule],
      }).compile();
      testService = moduleRef.get(TestService);
      process.env.API_HOST = provider.mockService.baseUrl;
    });

    const bodyExpectation = { hi: 'howdy there partner!' };

    describe('when a call is made to fetch the test str', () => {
      beforeAll(() => {
        provider.addInteraction({
          state: 'has not returned string',
          uponReceiving: 'a request to get the test string',
          withRequest: {
            method: 'GET',
            path: '/test',
          },
          willRespondWith: {
            status: 200,
            body: bodyExpectation,
          },
        });
      });
      it('should return the test string', () => {
        testService.getTestStr().subscribe(res => {
          expect(res).toHaveProperty('hi');
        });
      });
    });
  }
);
y
Hey dude, just about to have some dinner but have a quick scan of this https://pact-foundation.slack.com/archives/C9VBGLUM9/p1651074536722729?thread_ts=1650991865.991249&amp;cid=C9VBGLUM9 think you need a callback or await in there
☝️ 1
p
@Yousaf Nabi (pactflow.io) Wow! Thanks for the quick response and sorry to catch you so late. Believe it or not, I added the
done
function to my initial code snippet in my initial question, but removed it (hence the
(edited)
on my post 😞 . Using
done
unfortunately yields the same result. However, I did change the
it
to this:
Copy code
it('should return the test string', async () => {
        await testService
          .getTestStr()
          .toPromise()
          .then(res => {
            console.log('*** res: ', res);
            expect(res).toHaveProperty('hi');
          });
      });
which yielded a successful test:
Copy code
the test str should return the test string'
  console.log
    *** res:  { hi: 'howdy there partner!' }

      at src/app/pact/test.spec.ts:48:21

 PASS   project-api  apps/project/api/src/app/pact/test.spec.ts
  Pact between test consumer pact and test provider
    with 30000 ms timeout for Pact
      when a call is made to fetch the test str
        ✓ should return the test string (45 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.251 s, estimated 3 s
However, the problem is that it's not writing to the output folder with any Pact tests. Am I missing something? It does output but almost looks like it's outputting an empty log file in the specified
logDir
but never outputs an actual Pact file in the specified
dir
. Like I said, I'm doing this all in nestjs so maybe missing some config somewhere (total uneducated guess btw lol)? Another person at my org was trying to get Pact implemented in our nest layer but was running into this same issue which now I'm hitting as well. So we're obviously missing something really obvious but just not seeing it :(.
y
hmm, if you could stick a github repo up with an example, I can take a look at some point tomorrow or over the weekend, happy to cast some quick eyes over it.
p
For sure, I can't really post this repo as it's my company's, however I'll put something together tomorrow morning for you and post the link here. Thanks a TON again for your time @Yousaf Nabi (pactflow.io). You've been a great help.
y
Thanks buddy, yeah it's difficult sharing proprietary code but creating an example is the best way for me to help remotely, and has the added benefit of leaving a cookie trail for others in the future. Maybe take the nestjs pact example in pact-js and shimmy it around to arrange it like your code. Nice one Phil
p
@Yousaf Nabi (pactflow.io) Sorry, had to rewrite my reply as it was confusing as to why the nestjs layer is the consumer and not the UI. I didn't explain that well so just wanted to clarify to mitigate any confusion. At my company, the nestjs layer is simply a consumer of the backend API's and poses as an orchestration layer. So in our case, the java backend returns to then nestjs layer, not the UI. That's why our consumer tests will be in nestjs and not the UI. I didn't have the option to edit my reply, only delete and start over so here is the link to the github repo again, sorry for any confusion: https://github.com/philproof/pact-test-phil. The repo represents a 1 to 1 with my company's repo, for this test project in particular, and also results in the same error I'm seeing. If you need anything else please let me know. Thanks a TON for your time.
y
Thanks for taking the time to get something prepared, I really appreciate it, back today, so will try and take a look before the day is out.
p
@Yousaf Nabi (pactflow.io) Again, thanks so much. Really appreciate it!
👍 1
y
So, I've taken a look, lots to unpick there. basically it didn't look like your app actually made any external calls, therefore negating the need for Pact. I've converted it so it actually makes calls to an external provider, and updated the pact test to reflect. I think in the unit test, you should be using nest-js's framework to mock out the response of the httpclient, rather than just mocking the response of the method (the unit test I've added isn't very usefu). It is the encoding of the http request made by the client, and the expected response from the provider, that is encoded into a Pact. There is also the ability to use it for events, if you app is putting a message on a queue to example
First commit is getting the unit test working in the repo's initial setup https://github.com/philproof/pact-test-phil/pull/1/commits/f036ac5dfb418991f82bf1221e11f471534d0e97 2nd commit is converting it to make an external api call. Maybe I'm not clear on `rxjs`'s part as its the first time I've heard of it. let me know your thoughts man and I'll have a look tomorrow morn
p
@Yousaf Nabi (pactflow.io) That worked great and gives me a solid understanding of what I was doing incorrectly. You are right, we weren't hitting an endpoint via HttpService but were trying to scaffold out the base Pact implementation with a service that was returning a simple object. However, I didn't understand that was keeping the Pact test from running correctly and not starting the mock provider. So thanks again for all your help!
🙌 1
y
a-mazing buddy! Glad it's coming together a bit, took me a while to wrap my head round it when I first started.
rxjs
just looks like an events based alternative to promises so I think that is just a red herring, and not equivalent to the events based messages concept that Pact also caters for, whereas our example is using rest/http