From f96d782d26dd4815dbfd01de6ef7a647efd1f693 Mon Sep 17 00:00:00 2001 From: Brad Date: Mon, 25 Mar 2019 10:22:34 -0400 Subject: [PATCH] Improvement: Add act to update call to support hooks (#137) ### Summary Currently `render` and `fireEvent` are wrapped in `act` to support hooks. This pull request wraps the update call in `act` to support testing component updates (e.g. prop changes). ### Test plan * I have added a test for update in `__tests__/act.test.js`. * A useEffect hook should run again on `update` calls (if the hook dependency array is satisfied). --- docs/API.md | 2 +- src/__tests__/act.test.js | 8 ++++++++ src/render.js | 10 +++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/API.md b/docs/API.md index 01c7b7de..588e857b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -384,4 +384,4 @@ expect(submitButtons).toHaveLength(3); // expect 3 elements ## `act` -Useful function to help testing components that use hooks API. By default any `render` and `fireEvent` calls are wrapped by this function, so there is no need to wrap it manually. This method is re-exported from [`react-test-renderer`](https://github.com/facebook/react/blob/master/packages/react-test-renderer/src/ReactTestRenderer.js#L567]). +Useful function to help testing components that use hooks API. By default any `render`, `update`, and `fireEvent` calls are wrapped by this function, so there is no need to wrap it manually. This method is re-exported from [`react-test-renderer`](https://github.com/facebook/react/blob/master/packages/react-test-renderer/src/ReactTestRenderer.js#L567]). diff --git a/src/__tests__/act.test.js b/src/__tests__/act.test.js index db29ea4f..67f22ab7 100644 --- a/src/__tests__/act.test.js +++ b/src/__tests__/act.test.js @@ -28,6 +28,14 @@ test('render should trigger useEffect', () => { expect(effectCallback).toHaveBeenCalledTimes(1); }); +test('update should trigger useEffect', () => { + const effectCallback = jest.fn(); + const { update } = render(); + update(); + + expect(effectCallback).toHaveBeenCalledTimes(2); +}); + test('fireEvent should trigger useState', () => { const { getByTestId } = render(); const counter = getByTestId('counter'); diff --git a/src/render.js b/src/render.js index 14717542..b68690fc 100644 --- a/src/render.js +++ b/src/render.js @@ -26,7 +26,7 @@ export default function render( return { ...getByAPI(instance), ...queryByAPI(instance), - update: renderer.update, + update: updateWithAct(renderer), unmount: renderer.unmount, toJSON: renderer.toJSON, debug: debug(instance, renderer), @@ -46,6 +46,14 @@ function renderWithAct( return ((renderer: any): ReactTestRenderer); } +function updateWithAct(renderer: ReactTestRenderer) { + return function(component: React.Element) { + act(() => { + renderer.update(component); + }); + }; +} + function debug(instance: ReactTestInstance, renderer) { function debugImpl(message?: string) { return debugDeep(renderer.toJSON(), message);