React Testing Examples

react-testing-library
GitHubAbout
All examples

The component reads and updates a value from LocalStorage.

We test that the component renders the mocked value from LocalStorage. Then we type a new name into an input, submit the form, and test that the submitted value has been updated in LocalStorage.

We use @react-mock/localstorage to mock the cached data.

test.js
// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ name }) =>
render(
<LocalStorageMock items={{ name }}>
<PersistentForm />
</LocalStorageMock>
);
const submitForm = ({ getByText, getByLabelText }, { name }) => {
fireEvent.change(getByLabelText('Name'), { target: { value: name } });
fireEvent.click(getByText(/change name/i));
};
it('renders cached name', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ name: 'Trent' });
await waitForElement(() => getByText(/welcome, Trent/i));
});
describe('on update', () => {
it('renders updated name', async () => {
// Render new instance in every test to prevent leaking state
const utils = renderComponent({ name: 'Trent' });
submitForm(utils, { name: 'Trevor' });
await waitForElement(() => utils.getByText(/welcome, Trevor/i));
});
it('updates LocalStorage cache', () => {
// Render new instance in every test to prevent leaking state
const utils = renderComponent({ name: 'Trent' });
submitForm(utils, { name: 'Trevor' });
expect(localStorage.getItem('name')).toBe('Trevor');
});
});
// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ name }) =>
  render(
    <LocalStorageMock items={{ name }}>
      <PersistentForm />
    </LocalStorageMock>
  );

const submitForm = ({ getByText, getByLabelText }, { name }) => {
  fireEvent.change(getByLabelText('Name'), { target: { value: name } });
  fireEvent.click(getByText(/change name/i));
};

it('renders cached name', async () => {
  // Render new instance in every test to prevent leaking state
  const { getByText } = renderComponent({ name: 'Trent' });

  await waitForElement(() => getByText(/welcome, Trent/i));
});

describe('on update', () => {
  it('renders updated name', async () => {
    // Render new instance in every test to prevent leaking state
    const utils = renderComponent({ name: 'Trent' });
    submitForm(utils, { name: 'Trevor' });

    await waitForElement(() => utils.getByText(/welcome, Trevor/i));
  });

  it('updates LocalStorage cache', () => {
    // Render new instance in every test to prevent leaking state
    const utils = renderComponent({ name: 'Trent' });
    submitForm(utils, { name: 'Trevor' });

    expect(localStorage.getItem('name')).toBe('Trevor');
  });
});