-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
RTKQ: fetchFn using cross-fetch fails #1271
Comments
const request = new Request(url, config)
const response = await fetchFn(request)
|
So if I understand correctly I see several references to Is that a PR I can make to remove or modify those references to Also, as far as testing components that use RTKQ with jest, it seems my options are currently:
Is that roughly accurate? |
The weird thing is that even node-fetch seems to mention But the source code I linked above seems to indicate otherwise... so I honestly don't really know what's going on there. |
That's weird - they both worked when I was testing all of these things - we even used cross-fetch in a test. I can investigate if necessary. @RileyMShea Regarding testing with jest, feel free to look at the test setup for the repo. Jest runs in a node environment, so you're going to have to polyfill... we use node-fetch: //@ts-ignore
const nodeFetch = require('node-fetch')
//@ts-ignore
global.fetch = nodeFetch
//@ts-ignore
global.Request = nodeFetch.Request
const { server } = require('./src/query/tests/mocks/server')
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
process.on('unhandledRejection', (error) => {
// eslint-disable-next-line no-undef
fail(error)
}) |
Ah... I think I remember something from the old repo: It seems that Doing it by hand fixes that: import fetch, { Headers, Request, Response } from 'node-fetch';
import AbortController from 'abort-controller';
global.fetch = fetch as any;
global.Headers = Headers as any;
global.Request = Request as any;
global.Response = Response as any;
global.AbortController = AbortController; |
The following works fine for me:
import AbortController from 'abort-controller';
import { fetch, Headers, Request, Response } from 'cross-fetch';
import { server } from './src/server';
global.fetch = fetch;
global.Headers = Headers;
global.Request = Request;
global.Response = Response;
global.AbortController = AbortController;
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
import { setupServer } from 'msw/node';
import { authApiMock } from '@/services/auth/authApiMock';
import { eventsApiMock } from '@/services/events/eventsApiMock';
export const server = setupServer(...authApiMock, ...eventsApiMock); |
@donatoaguirre24 That is a super slick test setup. I was passing isomorphic-fetch to fetchFn and making actual API calls, but this is 100X better. I avoid needing cross-fetch in my bundle and my tests are fast thanks to msw. Thanks for all the help @phryneas @msutkowski @donatoaguirre24, and to the team for RTK. RTK is so good I feel guilty using it, esp now w/ RTKQ and its open API codegen. |
@RileyMShea Pro tip: Just add |
|
This was the only way how I got my tests running. Thanks for that 👍 (TestingLibrary+MSW+RTKQ+Jest). But I am still seeing the warning that fetch is not available:
Which is really puzzling, is this really the way to get fetchBaseQuery to "work" in a Jest environment? |
It matters when you do that. If So import order plays a role there |
Moved |
Wow. 3 hours of my life and that was the solution. Thank you. Testing the frontend is the hardest part of software development. 1 day to build the feature. 1 week if you try to write tests. |
So we've got |
Had the same issue and adding
into setup file helped for me |
We are migrating towards using RTK Query for API calls, and using `msw` to mock APIs in our tests. RTK Query's `fetchBaseQuery` requires the use of `fetch` and `Request`. `fetch()` was added to Node in v18, and the ability to use it in Jest tests was added to Jest in v28. However, it still cannot be used with a `jsdom` test environment. Therefore, it is necessary to add a polyfill. There are several libraries available for this but many others in this situation have had success using `whatwg-fetch` and so it was selected somewhat arbitrarily. It is also important that `whatwg-fetch` is imported before `fetchBaseQuery` (otherwise, a nuisance console warning will be issued). To ensure this happens, it is imported in a Jest setup file. References: reduxjs/redux-toolkit#2084 reduxjs/redux-toolkit#1271 jestjs/jest#13834
So far have had to stop jsdom declaring that tests are running in a browser: mswjs/msw#1786 Fiddle with whatwg-fetch polyfill: reduxjs/redux-toolkit#1271 Still more things to fix, some presumably a consequence of first issue.
When using
fetchFn
fromcreateApi
, isomorphic-fetch works but cross-fetch fails.Both seem to run fine in react without RTKQ. But with cross-fetch+RTKQ, a request that should be:
/some-endpoint
is run in the browser as
/[object%20Request]
.Possible I'm an idiot and flubbing the cross-fetch import and that's the problem, but I've tried a few
different import/require default/destructured variations and none seem to solve the issue.
Minimal Codesandbox example
https://codesandbox.io/s/vibrant-resonance-cvf7m?file=/src/services/pokemon.ts
The text was updated successfully, but these errors were encountered: