mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.99k stars 522 forks source link

Native fetch is intercepted, but openapi-fetch call makes actual request #2180

Open kellyrmilligan opened 5 months ago

kellyrmilligan commented 5 months ago

Prerequisites

Environment check

Node.js version

v18.17.0

Reproduction repository

https://codesandbox.io/p/devbox/focused-surf-k76656?workspaceId=924711ba-e34b-4725-9eb5-66c21523dbd6&layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clxhhfocx00053b85ch1p3hks%2522%252C%2522sizes%2522%253A%255B69.15559792921185%252C30.84440207078815%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clxhhfocx00023b85mg81fmuc%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clxhhfocx00033b85rjprrljz%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clxhhfocx00043b85dcacw5h7%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B100%252C0%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clxhhfocx00023b85mg81fmuc%2522%253A%257B%2522id%2522%253A%2522clxhhfocx00023b85mg81fmuc%2522%252C%2522activeTabId%2522%253A%2522clxhhwr99005m3b85hxsi5afj%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clxhhfocw00013b85rkodilqd%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%252C%257B%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fnode_modules%252F%2540inquirer%252Fconfirm%252Fpackage.json%2522%252C%2522id%2522%253A%2522clxhhwr99005m3b85hxsi5afj%2522%252C%2522mode%2522%253A%2522temporary%2522%257D%255D%257D%252C%2522clxhhfocx00043b85dcacw5h7%2522%253A%257B%2522tabs%2522%253A%255B%255D%252C%2522id%2522%253A%2522clxhhfocx00043b85dcacw5h7%2522%257D%252C%2522clxhhfocx00033b85rjprrljz%2522%253A%257B%2522id%2522%253A%2522clxhhfocx00033b85rjprrljz%2522%252C%2522activeTabId%2522%253A%2522clxhhgb0m001m3b85fbcu8is5%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clxhhgb0m001m3b85fbcu8is5%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522TERMINAL%2522%252C%2522shellId%2522%253A%2522clxhhgb3h001wdcg12jryh2bj%2522%257D%255D%257D%257D%252C%2522showDevtools%2522%253Afalse%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D

Reproduction steps

Current behavior

The first test using openapi-fetch fails, as it tries to make an actual fetch call. The second tests passes when just using native fetch.

Expected behavior

I expect the first test to pass as well. openapi-fetch just fetch under the hood, so I am not sure why it is not being intercepted nor counted as an outgoing request?

kellyrmilligan commented 5 months ago

have also tried jest-fixed-jsdom as well and am seeing the same behavior. I am in the early stages of the project i'm currently working on in terms of msw, so am switching back to v1 as I have used both openapi-fetch and msw v1 successfully in the past.

kellyrmilligan commented 5 months ago
fetch: baseFetch = globalThis.fetch,

https://github.com/drwpow/openapi-typescript/blob/main/packages/openapi-fetch/src/index.js#L28

is a bit of the relevant code

kellyrmilligan commented 5 months ago

https://github.com/drwpow/openapi-typescript

haggs commented 4 months ago

Hi @kellyrmilligan , for what it's worth I'm having the exact same issue (private repo can't share) but I've checked out your example codesandbox here, and forked it to show a workaround. If you provide your own fetch to createClient, it works, and MSW 2.0 can intercept the request. See client.ts in the linked sandbox^. This is a hack I've chosen to use in my codebase, but I'm not too happy about it.

githubjakob commented 4 months ago

Hi @haggs , can you please check your codesandbox link? It seems the link is broken. Thank you!

Edit: I just saw that the openapi-typescript repo has an example of how to test it with msw - so I assume it should work in principal.

rkofman commented 1 week ago

To summarize:

createClient in openapi-fetch has this line:

    fetch: baseFetch = globalThis.fetch,

which caches the value of fetch. However: msw overrides the value of fetch in server.listen (because that's where it applies the fetch interceptor).

Which means using both is fundamentally order-dependent, and server.listen must be called before creating a client with openapi-fetch.

This is also what the openapi-fetch documentation specifies:

// NOTE: server.listen must be called before createClient is used to ensure // the msw can inject its version of fetch to intercept the requests.

Since there is no way for msw to prevent another library from caching fetch before it has over-riden it, this issue can be closed in favor of https://github.com/openapi-ts/openapi-typescript/issues/1878, which contains a suggested workaround.

Is that correct?