使用 React 测试库为 React 上下文值设置值

Setting value for React context values with React testing library

我正在使用 react-testing-library 测试组件。该组件有一个警报,它接受来自上下文的道具以确定警报是否打开。

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>
      )}
   )
 }

所以上面的代码使用上下文从PeopleContext中拉取personSuccessAlert的值。如果 personSuccessAlert 为真,将显示警报。我的上下文文件设置如下:

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;

现在我正在尝试开发一个将 personSuccessAlert = true 传递给 PersonRecord 组件的测试。

这是我一直在尝试的:

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();
  });
});

我尝试了 const providerProps = { value: true }; 的不同变体。将 value 替换为 personSuccessAlert 无效。

如有任何建议或帮助,我们将不胜感激。

您正在将 providerProps 传递给 PeopleContextProvider,但是 PeopleContextProvider 没有对 props 做任何事情。您需要实际使用这些道具,例如设置初始状态。你可以尝试这样的事情:

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>
  );
};

这将允许您通过传入 initialPersonSuccessAlert 属性来设置 personSuccessAlert 的初始状态。您可以像这样更新您的测试:

const providerProps = { initialPersonSuccessAlert: true };

或者,如果您只想在测试文件中进行更改,您可以考虑更新 renderWithEmptyPerson 函数以直接使用 PeopleContext.Provider 而不是 PeopleContextProvider 组件。这将允许您根据需要设置上下文值。