-
Notifications
You must be signed in to change notification settings - Fork 31
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
Philosophy in regards to Jest fake timers #4
Comments
This is a great question. I honestly have no idea :-( |
@slightlytyler Good point. We could use runWithRealTimers - Could you show us some code where you feel that using BOTH wait and jest fake timers might make sense? It might help us to visualize this problem better. |
One thing that comes to my mind now - on the import of wait-for-expect we could do a side-effect like: const realSetTimeout = setTimeout and then use that when actually calling the function, so we wouldn't care if anything overwrote the globals meanwhile. @slightlytyler If you are able to show us some code examples - breaking repro would be amazing :-) I can try to get it to pass |
I can probably add a failing case for you. A trivial example exposes the problem. Consider a search box that debounces input before calling a handler => which results in promises added to the queue => with an eventual rerender when the data resolves. We'll need to wait not only for the promises to resolve (what we need |
Makes sense! |
This is tricky! Personally I'd rather not encode jest-specific stuff into this package. I have an idea of something to do if you could provide a simple example that I could update (you may even be able to use codesandbox). |
Doesn't look like codesandbox supports fake timers but here y'all go https://github.com/slightlytyler/wait-for-expect-fake-timers |
Thanks so much! I will try to squeeze in a bit time today to try to make it pass. I agree that it would be best to not make anything jest-specific here. |
@slightlytyler jest.useFakeTimers();
describe("SlowSearchBox", () => {
it("should show results", async () => {
const { getByTestId } = render(<SlowSearchBox />);
Simulate.change(getByTestId("input"), {
target: {
value: "baco"
}
});
jest.runAllTimers();
});
}); Looks like the jest fake timers doesn't play nice with debounce, when I changed your code to: let debounce;
(..)
search = () => {
clearTimeout(debounce)
debounce = setTimeout(
() => this.setState({results: findEmojis(this.state.query)}),
2000
);
} it clicked and worked, but I didn't need to use waitForExpect: jest.runAllTimers();
expect(getByTestId("result-list")).toBeInTheDOM()
expect(getByTestId("result-item")).toBeInTheDOM()
expect(getByTestId("result-list")).toHaveTextContent("🥓") worked fine. Adding: const setTimeout = global.setTimeout; at the top of wait-for-expect fixes this particular problem. And it's not really jest specific. It would take care of making this lib compatible with any library that messes up with the setTimeout. What do you think @kentcdodds ? |
Interesting. I was going to look into and suggest possibly calling I'm pretty happy with that solution ( That said, as far as I'm concerned we can make the assumption that there will be a global |
@lgandecki you're right I messed up the example (thanks |
@kentcdodds can confirm |
Cool (also I'm a little confused why this works... I would expect Jest to fake out all timers regardless of whether it's on global or window). So this isn't really my lib, but what I'd recommend is adding this to the top of the file here: // Used to avoid using Jest's fake timers.
// See https://github.com/TheBrainFamily/wait-for-expect/issues/4 for more info
const setTimeout = (typeof window !== 'undefined' ? window : global).setTimeout |
@kentcdodds what happens is - jest overwrites the global setTimeout, but if you assign it to a local variable before that then your local one stays unchanged. |
As this isn't impacting me personally at the moment, I'll leave this for @slightlytyler to implement :) |
I'm exploring deprecating
flushPromises
in my own project (not usingreact-test-library
) in favor of await
approach based on this library. The one flaw I see is that this library fails when using fake timers. How do you suggest users approach this problem?The text was updated successfully, but these errors were encountered: