vadimdemedes/ink-testing-library

`act` equivalent or flush effects on render

Open

#3 aperta il 17 mar 2019

Vedi su GitHub
 (13 commenti) (8 reazioni) (0 assegnatari)TypeScript (22 fork)user submission
enhancementhelp wanted

Metriche repository

Star
 (152 star)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

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.

Guida contributor