Open xsjcTony opened 1 year ago
This is an issue with @testing-library/react
. See https://github.com/testing-library/react-testing-library/issues/1197
Trick this piece of code into recognizing your environment as Jest.
globalThis.jest = 'neitherUndefinedNorNull'
@ph-fritsche Thanks a lot, I got what the problem is.
But regarding your solutions, I think for a temporary workaround, this makes more sense to me https://github.com/wojtekmaj/react-async-button/commit/2d26f217a375b7020ddf42f76891254586fc3ce4
Is there any ETA to fix this issue? since I personally don't like temp workaround to be there forever in my code🤣
Regarding the fix, just like letting users pass advanceTimer
option in userEvent.setup()
, instead of using jest.advanceTimersByTime
, this should be testing-framework agnostic, since there are also some ppl like me who had never used Jest
In your test suites using fake timers
import { beforeAll, vi, describe } from 'vitest';
describe('this suite uses fake timers', () => {
// Temporarily workaround for bug in @testing-library/react when use user-event with `vi.useFakeTimers()`
beforeAll(() => {
const _jest = globalThis.jest;
globalThis.jest = {
...globalThis.jest,
advanceTimersByTime: vi.advanceTimersByTime.bind(vi)
};
return () => void (globalThis.jest = _jest);
});
})
I ran into same problem today. My work around:
beforeEach(() => {
vi.useFakeTimers()
globalThis.jest = {
advanceTimersByTime: vi.advanceTimersByTime.bind(vi),
}
})
beforeAll(() => {
vi.useRealTimers()
})
test('given a new recurring question submitted: form data contains only question text', async () => {
...
const user = userEvent.setup({
advanceTimers: vi.advanceTimersByTime.bind(vi),
})
})
This worked but causes a Warning: An update to RouterProvider inside a test was not wrapped in act(...).
warning.
Would appreciate if y'all fixed this. Testing library should work out of the box with Vitest imo.
Should this be added to documentation somewhere? I spent a few hours trying to get my tests with fake timers migrated from Jest to Vite. This solved most of my issues. It would be great to have this in the docs somewhere??
Thank you to the comments above; this saved me a lot of time! I encountered the same thing while moving a test from jest to vitest.
Here's my version of the workaround, with business logic removed, in case it helps some future human (or LLM?).
There aren't any act warnings, and my tests still fail when expected. (I recognize this is very similar to something that OP explicitly said was not working for them, so ymmv.)
describe('myTestSubject', () => {
beforeEach(() => {
vi.useFakeTimers();
});
// seems like there's a bug in the interaction between userEvent / vi.useFakeTimers
// see: https://github.com/testing-library/user-event/issues/1115
const getUserEventInstance = () =>
userEvent.setup({
advanceTimers: vi.advanceTimersByTime.bind(vi),
});
it(`has some timer-based user interaction`, async () => {
const { getBySomething } = render(<TestComponent />);
const user = getUserEventInstance();
await act(() => user.click(getBySomething(something)));
await act(() => user.keyboard('a'));
// (assert)
vi.advanceTimersByTime(t);
// (assert)
});
});
Hey there. I ran into this issue when migrating Jest to Vitest. After trying out different solutions, the easiest one was adding this line to the setup files:
vi.stubGlobal('jest', { advanceTimersByTime: vi.advanceTimersByTime.bind(vi) });
combined with:
const user = userEvent.setup({ delay: null });
although the only actual change was the first one, since the other one was needed to make Jest work.
Hope this help.
Happy coding.
userEvent
Using delay: null
is not recommended: https://testing-library.com/docs/user-event/options/#advancetimers
Reproduction example
https://stackblitz.com/edit/vitejs-vite-askvcq?file=src/__tests__/App.test.tsx
Prerequisites
Describe the bug
I have a React component which is a timer (minimal reproduction), that starts automatically after mounted, and there's a button to RESET the timer.
In the test, I'm using
vi.useFakeTimers()
andawait vi.advanceTimersByTimeAsync(500)
to test the timer segmentally.However, I'm not able to use
await user.click()
to click the button.This is a known issue with fake timers, however, none of the existing solutions works.
None of these works
And I cannot use
vi.useRealTimers()
before clicking button, since it will break the fake timer to further test the component's reset functionality.Those solutions above are all based on
Jest
since almost all resources on the internet are forJest
. But since I've never usedJest
, so I'm not sure if it's working inJest
, and is this an issue with@testing-library/user-event
orVitest
Expected behavior
The button is successfully clicked
Actual behavior
It makes the test timed out
User-event version
14.0.0
Environment
Additional context
Please also refer to https://github.com/vitest-dev/vitest/issues/3184