Home > Net >  Setting value for React context values with React testing library
Setting value for React context values with React testing library

Time:10-05

I am working on testing a component using react-testing-library. The component has an alert which accepts a prop that comes from context to determine whether the alert is open or not.

const PersonRecord = () => {

  const {
    personSuccessAlert,
    setPersonSuccessAlert,
    updatePersonSuccessAlert,
    setUpdatePersonSuccessAlert,
  } = useContext(PeopleContext);

  return (
      {personSuccessAlert && (
        <div className="person-alert-container">
          <Alert
            ariaLabel="person-create-success-alert"
            icon="success"
            open={personSuccessAlert}
          />
        </div>
      )}
   )
 }

So the above code uses context to pull the value of personSuccessAlert from PeopleContext. If personSuccessAlert is true the alert will display. My context file is set up as follows:

import React, { createContext, useState } from 'react';

export const PeopleContext = createContext();

const PeopleContextProvider = ({ children }) => {
  const [personSuccessAlert, setPersonSuccessAlert] = useState(false);
  const [updatePersonSuccessAlert, setUpdatePersonSuccessAlert] = useState(
    false,
  );

  return (
    <PeopleContext.Provider
      value={{
        personSuccessAlert,
        updatePersonSuccessAlert,
        setPersonSuccessAlert,
        setUpdatePersonSuccessAlert,
      }}>
      {children}
    </PeopleContext.Provider>
  );
};

export default PeopleContextProvider;

Now I am trying to develop a test which passes personSuccessAlert = true to the PersonRecord component.

Here is what I have been trying:

export function renderWithEmptyPerson(
  ui,
  {
    providerProps,
    path = '/',
    route = '/',
    history = createMemoryHistory({ initialEntries: [route] }),
  },
) {
  return {
    ...render(
      <MockedProvider mocks={getEmptyPerson} addTypename={false}>
        <PeopleContextProvider {...providerProps}>
          <Router history={history}>
            <Route path={path} component={ui} />
          </Router>
        </PeopleContextProvider>
      </MockedProvider>,
    ),
  };
}

describe('empty person record rendering', () => {
  afterEach(cleanup);
  test('empty person', async () => {

    const providerProps = { value: true };

    const { getByText, queryByText, queryByLabelText } = renderWithEmptyPerson(
      PersonRecord,
      {
        providerProps,
        route: 'people/6d6ed1f4-8294-44de-9855-2999bdf9e3a7',
        path: 'people/:slug',
      },
    );
    expect(getByText('Loading...')).toBeInTheDocument();
  });
});

I have tried different variations of const providerProps = { value: true };. Replacing value with personSuccessAlert did not work.

Any advice or help is appreciated.

CodePudding user response:

You are passing providerProps to the PeopleContextProvider, but the PeopleContextProvider is not doing anything with the props. You'll need to actually use those props, for example to set the initial state. You could try something like:

const PeopleContextProvider = ({ children, initialPersonSuccessAlert = false }) => {
  const [personSuccessAlert, setPersonSuccessAlert] = useState(initialPersonSuccessAlert);
  const [updatePersonSuccessAlert, setUpdatePersonSuccessAlert] = useState(
    false,
  );

  return (
    <PeopleContext.Provider
      value={{
        personSuccessAlert,
        updatePersonSuccessAlert,
        setPersonSuccessAlert,
        setUpdatePersonSuccessAlert,
      }}>
      {children}
    </PeopleContext.Provider>
  );
};

This would allow you to set the initial state of personSuccessAlert by passing in a initialPersonSuccessAlert prop. You could update your test like so:

const providerProps = { initialPersonSuccessAlert: true };

Alternatively, if you only wanted to make changes in your test file, you could consider updating the renderWithEmptyPerson function to use PeopleContext.Provider directly instead of the PeopleContextProvider component. That will allow you to set the context value however you like.

  • Related