enhancementhelp wanted
倉庫指標
- 星標
- (152 顆星)
- PR 合併指標
- (30 天內沒有已合併 PR)
描述
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.