vadimdemedes/ink-testing-library

`act` equivalent or flush effects on render

Open

#3 建立於 2019年3月17日

在 GitHub 查看
 (13 留言) (8 反應) (0 負責人)TypeScript (152 star) (22 fork)user submission
enhancementhelp wanted

描述

Testing a component with hooks is a bit of an issue currently. I have this as an example component that renders & ends the application:

export const Cancelled = () => {
  const { exit } = useContext(AppContext);

  useEffect(() => {
    exit();
  }, [exit]);

  return <Box>Cancelled!</Box>;
};

And I'm testing it like this:

it('should render and exit', () => {
    const exit = sinon.spy();
    const { lastFrame, unmount } = render(
        <AppContext.Provider value={{ exit }}>
          <Cancelled />
        </AppContext.Provider>
    );

    expect(lastFrame()).to.matchSnapshot();
    expect(exit.calledOnce).to.equal(true);

    unmount();
});

The problem is the effect doesn't run by the time the render completes. I have to wrap the check around exit.calledOnce in a setTimeout. An act equivalent would allow use to write something like this:

it('should render and exit', () => {
    let lastFrame, unmount;
    const exit = sinon.spy();
    act(() => {
        ({ lastFrame, unmount } = render(
            <AppContext.Provider value={{ exit }}>
              <Cancelled />
            </AppContext.Provider>
        ));
    });

    expect(lastFrame()).to.matchSnapshot();
    expect(exit.calledOnce).to.equal(true);

    unmount();
});

and we'd know the effects would have been flushed by the time we check exit.calledOnce.

Alternatively, this version of render could flush effects immediately, rather than using the scheduler, which uses setTimeout.

貢獻者指南