Functions in a jest test only work when launched alone, but not at the same time

I have a custom hook that updates a state. The state is made with immer thanks to useImmer().

I have written the tests with Jest & "testing-library" - which allows to test hooks -.

All the functions work when launched alone. But when I launch them all in the same time, only the first one succeed. How so?

Here is the hook: (simplified for the sake of clarity):

export default function useSettingsModaleEditor(draftPage) {
  const [settings, setSettings] = useImmer(draftPage);
  
  const enablePeriodSelector = (enable: boolean) => {
    return setSettings((draftSettings) => {
      draftSettings.periodSelector = enable;
    });
  };

  const enableDynamicFilter = (enable: boolean) => {
    return setSettings((draftSettings) => {
      draftSettings.filters.dynamic = enable;
    });
  };

  const resetState = () => {
    return setSettings((draftSettings) => {
      draftSettings.filters.dynamic = draftPage.filters.dynamic;
      draftSettings.periodSelector = draftPage.periodSelector;
      draftSettings.filters.static = draftPage.filters.static;
    });
  };

  return {
    settings,
    enablePeriodSelector,
    enableDynamicFilter,
    resetState,
  };
}

And the test:

describe("enablePeriodSelector", () => {
  const { result } = useHook(() => useSettingsModaleEditor(page));
  it("switches period selector", () => {
    act(() => result.current.enablePeriodSelector(true));
    expect(result.current.settings.periodSelector).toBeTruthy();
    act(() => result.current.enablePeriodSelector(false));
    expect(result.current.settings.periodSelector).toBeFalsy();
  });
});

describe("enableDynamicFilter", () => {
  const { result } = useHook(() => useSettingsModaleEditor(page));
  it("switches dynamic filter selector", () => {
    act(() => result.current.enableDynamicFilter(true));
    expect(result.current.settings.filters.dynamic).toBeTruthy();
    act(() => result.current.enableDynamicFilter(false));
    expect(result.current.settings.filters.dynamic).toBeFalsy();
  });
});

describe("resetState", () => {
  const { result } = useHook(() => useSettingsModaleEditor(page));
  it("switches dynamic filter selector", () => {
    act(() => result.current.enableDynamicFilter(true));
    act(() => result.current.enablePeriodSelector(true));
    act(() => result.current.addShortcut(Facet.Focuses));
    act(() => result.current.resetState());
    expect(result.current.settings.periodSelector).toBeFalsy();
    expect(result.current.settings.filters.dynamic).toBeFalsy();
    expect(result.current.settings.filters.static).toEqual([]);
  });
});

All functions works in real life. How to fix this? Thanks!

2 answers

  • answered 2021-01-15 15:38 Siddharth Pachori

    use beforeEach and reset all mocks(functions has stale closure data) or make common logic to test differently and use that logic to test specific cases.

  • answered 2021-01-15 15:57 DoneDeal0

    The answer was: useHook is called before "it". It must be called below.