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

MSW doesn't resolve with Jest 28 .useFakeTimers() #1390

Closed
4 tasks done
harry-gocity opened this issue Sep 5, 2022 · 9 comments
Closed
4 tasks done

MSW doesn't resolve with Jest 28 .useFakeTimers() #1390

harry-gocity opened this issue Sep 5, 2022 · 9 comments
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node

Comments

@harry-gocity
Copy link

harry-gocity commented Sep 5, 2022

Prerequisites

Environment check

  • I'm using the latest msw version
  • I'm using Node.js version 14 or higher

Node.js version

14, 16, 18 (we are on 16)

Reproduction repository

https://github.com/harry-gocity/msw-examples/tree/repro

Reproduction steps

Switch to 'repro' branch
Run the tests in examples/with-jest
Test fails as MSW resolver does not respond

Current behavior

This has come up before (#448, #966, and elsewhere here and similarily here) but I can't find a solution when using fetch (polyfilled with whatwg-fetch and Jest 27 / 28. Please feel free to close this issue and direct me elsewhere if this isn't the case!

I believe that this issue could be to do with jest mocking out functions used by MSW (setTimeout, nextTick etc) but skipping these via Jest's selective faking has no effect.

#1125 suggests it may be due to node version, but that's marked as solved.

Expected behavior

MSW resolver should respond

@harry-gocity harry-gocity added bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node labels Sep 5, 2022
@milesrichardson
Copy link

Not sure, but this sounds related to to changes in Jest global injection, which will cause it to inject the node-native fetch, which will not be intercepted. I recommend verifying that your tests are using the polyfilled whatwg-fetch and not the node native fetch.

Here's a PR where I fixed a similar issue (see the first commit). You might find some helpful information in there. This PR is part of a series of PRs to add support for native fetch and migrate msw development and CI to Node 18.

The root problem is that msw does not intercept native fetch in Node 18. I have some PRs in progress to fix this. See my recent comment on #1388 for summary and discussion.

@harry-gocity
Copy link
Author

harry-gocity commented Nov 10, 2022

Hi @milesrichardson, In the repro above this is also an issue on Node 16 and 14. Have updated the issue description. There is some discussion in #1388 around using cross-fetch or node-fetch instead but neither solve the issue either.

@ronkot
Copy link

ronkot commented Mar 13, 2023

Just adding my 2 cents. We encountered two kind of weird problems using the latest msw version (1.1 or something):

  • ReferenceError: setTimeout is not defined when calling server.close() (doc : jest fake timers : expect on setTimeout not working jestjs/jest#11713 (comment))
  • Runtime handler configs (server.use()) were not always taking precence. By logging the handlers it seemed that the runtime handler was there but response was delivered from default handlers. The behaviour was not deterministic - on some runs runtime handler was called and in some runs not.

Both problems were fixed by downgrading to msw@0.41.1. I found this working version by binary searching through msw versions. So it seems that from 0.42.0 onwards something changed with timers (or something..)

My setup:

  • Node 16.13.2
  • Jest 27.5.1
  • whatwg-fetch 3.6.2

@TrAndreiR
Copy link

Any updates regarding this issue?

@harry-gocity
Copy link
Author

harry-gocity commented Nov 3, 2023

Currently upgrading to v2, with Node 20.9, and now on Jest 29. The following config seems to work:

const mockDate = new Date(2022, 6, 26);

beforeEach(() => {
    jest.useFakeTimers({
        now: mockDate,
        doNotFake: ['queueMicrotask'],
    });
});

afterEach(() => {
    jest.useRealTimers();
});

@kettanaito
Copy link
Member

I confirm that you should be doNotFake: ['queueMicrotask'] with Jest's useFakeTimers to prevent Jest from stopping any scheduled microtasks in the process. We are working on updating the documentation to feature this as well.

@harry-gocity
Copy link
Author

Cheers @kettanaito - have to say upgrading our codebase from v1 -> v2 (~150 rest resolvers) was an absolute breeze, largely thanks to the fantastic new docs 🎉

@kettanaito
Copy link
Member

Thank you, @harry-gocity! It means a lot to me to hear that! Writing the new docs took a ton of time. I'm happy to see that time paying off.

@tomdglenn91
Copy link

Just commenting here as I'm currently on msw 0.x and this solution does not work for me. However if I add setTimeout' it does work. No idea if this is the 'correct' approach, all I know is before this code, it did not work, and after adding it, now it does.

  jest.useFakeTimers({
      doNotFake: ['setTimeout'],
    });

Thanks @kettanaito for getting me 99% of the way there, hopefully this helps someone out who stumbles along this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node
Projects
None yet
Development

No branches or pull requests

6 participants