Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest spy doesn't work on Microservices Controller (EventPattern) E2E Tests #13473

Closed
5 of 15 tasks
elton-okawa opened this issue Apr 21, 2024 · 2 comments
Closed
5 of 15 tasks
Labels
needs triage This issue has not been looked into

Comments

@elton-okawa
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

  1. Spying on Controller instance - handler is called but spy does not track it
  2. Spying on Controller prototype before app is initialized - handler is not called
  3. Spying on Controller prototype after app is initialized - handler is called but spy does not track it

Minimum reproduction code

https://github.com/elton-okawa/nestjs-spy-controller-issue

Steps to reproduce

npm install

// run all tests
npm run test:e2e

// run individual tests (better to see logs)
npm run test:e2e -- -t 'should spy controller instance'
npm run test:e2e -- -t 'should spy controller prototype before init'
npm run test:e2e -- -t 'should spy controller prototype after init'

Expected behavior

From a similar issue comment: #8790 (comment)
(As the comment suggests, I couldn't find any related issue besides this one)

Long story short: you can spy on/mock service methods. You can't spy on/mock controller methods (annotated methods) after your app is initialized (execution context is created).

I understood that it's possible to spy/mock annotated methods as long as you do it before the app is initialized, so behavior (1) and (3) is expected to fail, but not (2)

Package

  • I don't know. Or some 3rd-party package
  • @nestjs/common
  • @nestjs/core
  • @nestjs/microservices
  • @nestjs/platform-express
  • @nestjs/platform-fastify
  • @nestjs/platform-socket.io
  • @nestjs/platform-ws
  • @nestjs/testing
  • @nestjs/websockets
  • Other (see below)

Other package

No response

NestJS version

10.3.8

Packages versions

[System Information]
OS Version     : Linux 5.15.146.1-microsoft-standard-WSL2
NodeJS Version : v20.11.1
NPM Version    : 10.2.4

[Nest CLI]
Nest CLI Version : 10.3.2

[Nest Platform Information]
platform-express version : 10.3.8
microservices version    : 10.3.8
schematics version       : 10.1.1
testing version          : 10.3.8
common version           : 10.3.8
core version             : 10.3.8
cli version              : 10.3.2

Node.js version

20.11.1

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

  1. Spying on Controller instance - handler is called but spy does not track it
[Nest] 47442  - 04/21/2024, 7:28:41 AM   DEBUG [E2E Test] Producing message...
[Nest] 47442  - 04/21/2024, 7:28:41 AM   DEBUG [E2E Test] Message produced successfully!
[Nest] 47442  - 04/21/2024, 7:28:41 AM   DEBUG [E2E Test] Waiting "message to be consumed" for 10000ms...
[Nest] 47442  - 04/21/2024, 7:28:41 AM     LOG [AppService] Message received: "spy controller instance"
[Nest] 47442  - 04/21/2024, 7:28:51 AM   DEBUG [E2E Test] Finished waiting for "message to be consumed"
[Nest] 47442  - 04/21/2024, 7:28:51 AM   DEBUG [E2E Test] Message should be consumed at this point
...

  ● AppController (e2e) › controller › should spy controller instance

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

      60 |       await produceEventAndWait(producer, 'spy controller instance');
      61 |
    > 62 |       expect(handlerSpy).toHaveBeenCalledTimes(1);
         |                          ^
      63 |     });
      64 |
      65 |     it('should spy controller prototype before init', async () => {

      at Object.<anonymous> (test/app.e2e-spec.ts:62:26)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 5 skipped, 6 total
Snapshots:   0 total
Time:        44.32 s, estimated 249 s
Ran all test suites with tests matching "should spy controller instance".
  1. Spying on Controller prototype before app is initialized - handler is not called
[Nest] 48666  - 04/21/2024, 7:31:55 AM   DEBUG [E2E Test] Producing message...
[Nest] 48666  - 04/21/2024, 7:31:55 AM   DEBUG [E2E Test] Message produced successfully!
[Nest] 48666  - 04/21/2024, 7:31:55 AM   DEBUG [E2E Test] Waiting "message to be consumed" for 10000ms...
[Nest] 48666  - 04/21/2024, 7:32:05 AM   DEBUG [E2E Test] Finished waiting for "message to be consumed"
[Nest] 48666  - 04/21/2024, 7:32:05 AM   DEBUG [E2E Test] Message should be consumed at this point
...


  ● AppController (e2e) › controller › should spy controller prototype before init

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

      72 |       );
      73 |
    > 74 |       expect(handlerSpy).toHaveBeenCalledTimes(1);
         |                          ^
      75 |     });
      76 |
      77 |     it('should spy controller prototype after init', async () => {

      at Object.<anonymous> (test/app.e2e-spec.ts:74:26)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 5 skipped, 6 total
Snapshots:   0 total
Time:        51.975 s
Ran all test suites with tests matching "spy controller prototype before init".
  1. Spying on Controller prototype after app is initialized - handler is called but spy does not track it
[Nest] 49480  - 04/21/2024, 7:33:57 AM   DEBUG [E2E Test] Producing message...
[Nest] 49480  - 04/21/2024, 7:33:57 AM   DEBUG [E2E Test] Message produced successfully!
[Nest] 49480  - 04/21/2024, 7:33:57 AM   DEBUG [E2E Test] Waiting "message to be consumed" for 10000ms...
[Nest] 49480  - 04/21/2024, 7:33:57 AM     LOG [AppService] Message received: "spy controller prototype after init"
[Nest] 49480  - 04/21/2024, 7:34:07 AM   DEBUG [E2E Test] Finished waiting for "message to be consumed"
[Nest] 49480  - 04/21/2024, 7:34:07 AM   DEBUG [E2E Test] Message should be consumed at this point
...

 ● AppController (e2e) › controller › should spy controller prototype after init

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

      84 |       );
      85 |
    > 86 |       expect(handlerSpy).toHaveBeenCalledTimes(1);
         |                          ^
      87 |     });
      88 |   });
      89 | });

      at Object.<anonymous> (test/app.e2e-spec.ts:86:26)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 5 skipped, 6 total
Snapshots:   0 total
Time:        44.39 s, estimated 52 s
Ran all test suites with tests matching "spy controller prototype after init".
@elton-okawa elton-okawa added the needs triage This issue has not been looked into label Apr 21, 2024
@esahin90
Copy link
Contributor

This is the root of the issue. The function is not called on the instance, but rather on the prototype
https://github.com/nestjs/nest/blob/master/packages/microservices/listener-metadata-explorer.ts#L50

@kamilmysliwiec
Copy link
Member

Let's track this here #14112

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage This issue has not been looked into
Projects
None yet
Development

No branches or pull requests

3 participants