Unable to clear cache in unit tests
See original GitHub issueI’m writing unit tests for a selector that depend on external state via an HTTP request.
I’ve mocked the HTTP request and response, but noticed that when test N+1 uses the same selector, as test N, the selector does not get re-evaluated for test N+1, but returns the value cached for test N.
Here’s an example:
import { atom, selector, snapshot_UNSTABLE } from "recoil";
const numberState = atom({ key: "Number", default: 1 });
const callApiToGetMultiplier = jest.fn();
const multipliedState = selector({
key: "MultipliedNumber",
get: ({ get }) => get(numberState) * callApiToGetMultiplier()
});
beforeEach(() => {
callApiToGetMultiplier.mockClear();
});
test("First test", () => {
callApiToGetMultiplier.mockReturnValueOnce(100);
const initialSnapshot = snapshot_UNSTABLE();
expect(initialSnapshot.getLoadable(multipliedState).valueOrThrow()).toBe(100);
expect(callApiToGetMultiplier).toBeCalledTimes(1);
});
test("Second test", () => {
callApiToGetMultiplier.mockReturnValueOnce(200);
const initialSnapshot = snapshot_UNSTABLE();
// FAILS because value is still 100
expect(initialSnapshot.getLoadable(multipliedState).valueOrThrow()).toBe(200);
// FAILS because callApiToGetMultiplier is not called (again)
// expect(callApiToGetMultiplier).toBeCalledTimes(1);
});
And here it is on CodeSandbox: https://codesandbox.io/s/optimistic-hooks-3714i?file=/src/repro.test.js:0-938
At https://recoiljs.org/docs/guides/testing#example-jest-unit-testing-selectors it says:
You can build a fresh snapshot using
snapshot_UNSTABLE()
and then use that Snapshot to evaluate selectors for testing.
As the failing test shows, the returned snapshot is not entirely fresh, which is problematic for isolating unit tests.
I’m aware of https://github.com/facebookexperimental/Recoil/issues/972#issuecomment-962996375, but the “solution” there, as well as https://github.com/facebookexperimental/Recoil/pull/1413 both rely on hooks, which are not available in this context.
As far as I know there’s no non-hook API to do a similar refresh, but I’d argue that this shouldn’t be needed anyway, unless the above documentation is incorrect and snapshot_UNSTABLE()
is not supposed to return a fresh snapshot.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
@FokkeZB - I was working on #1498 for another use case. It might be a little bit awkward, but it does allow users to refresh selector caches from snapshots without hooks.
Worked great!
Doc update: https://github.com/facebookexperimental/Recoil/pull/1619