Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 单元测试对访问全局存储的组件进行反应_Reactjs_Unit Testing_Jestjs_React Testing Library - Fatal编程技术网

Reactjs 单元测试对访问全局存储的组件进行反应

Reactjs 单元测试对访问全局存储的组件进行反应,reactjs,unit-testing,jestjs,react-testing-library,Reactjs,Unit Testing,Jestjs,React Testing Library,首先,请让我知道这是不是提出这个问题的正确地方,或者把它移到正确的地方 我开始为一些React组件编写单元测试。其中一个没有任何道具,但依赖于商店: const PlayerSelector = () => { const classes = useStyles(); const divRef = useRef(null); const [{ playerList }, dispatch] = useStore(); ... 其中userStore()来自: export c

首先,请让我知道这是不是提出这个问题的正确地方,或者把它移到正确的地方

我开始为一些React组件编写单元测试。其中一个没有任何道具,但依赖于
商店

const PlayerSelector = () => {
  const classes = useStyles();
  const divRef = useRef(null);
  const [{ playerList }, dispatch] = useStore();
...
其中
userStore()
来自:

export const StateContext = createContext(null);

export const StoreProvider = ({ initialState, reducer, children }) => (
  <StateContext.Provider
    value={useReducer(reducer, initialState)}
  >
    {children}
  </StateContext.Provider>
);

export const useStore = () => useContext(StateContext);
结果是
TypeError:objectnull不可iterable(无法读取属性符号(Symbol.iterator))
指向此行:

const [{ firmList }, dispatch] = useStore();

在谷歌搜索了很多之后,我发现了一些有用的资源,说明了如何模拟上下文,但没有说明如何对减速机进行同样的操作。我不知道我是否把事情复杂化了,是否应该找到另一种测试方法,或者我是否遗漏了一个明显的答案。在任何情况下,我都非常感谢您提供的任何提示或指导。

当您测试一个组件,该组件使用来自提供者的上下文时,您还需要呈现提供者以提供上下文。
render
接受第二个options参数,该参数可以包含一个用于包装正在测试的组件的参数

例如:

const customWrapper = ({ children }) => <SomeProvider>{children}</SomeProvider>;

it('loads component', () => {
  const { queryByRole } = render(
    <PlayerSelector />,
    {
      wrapper: customWrapper
    },
  );
  expect(queryByRole('button')).toHaveAttribute('aria-label');
});
如果您发现自己需要大量编写包装器实用程序,您还可以创建一个,它或多或少地重复了上述内容

const StateProvider = ({ children }) => (
  <StoreProvider
    initialState={{}} // <-- any initial state object
    reducer={rootReducerFunction} // <-- any reducer function
  >
    {children}
  </StoreProvider>
);

export const renderWithState = (ui, options) => {
  return render(ui, { wrapper: StateProvider, ...options });
}
const StateProvider=({children})=>(
{
const{queryByRole}=renderWithState();
expect(queryByRole('button')).toHaveAttribute('aria-label');
});

你是救命恩人!我实现了您的建议,然后通过导入包含存储内容的.js文件来模拟initialState。最后,我不得不将PlayerSelection组件封装在MemoryRouter中。我想让你知道,我非常感谢你花时间回答我的问题,为我指出正确的方向。非常感谢你!
it('loads component', () => {
  const { queryByRole } = render(
    <PlayerSelector />,
    {
      wrapper: ({ children }) => (
        <StoreProvider
          initialState={{}} // <-- any initial state object
          reducer={rootReducerFunction} // <-- any reducer function
        >
          {children}
        </StoreProvider>
      ),
    },
  );
  expect(queryByRole('button')).toHaveAttribute('aria-label');
});
const StateProvider = ({ children }) => (
  <StoreProvider
    initialState={{}} // <-- any initial state object
    reducer={rootReducerFunction} // <-- any reducer function
  >
    {children}
  </StoreProvider>
);

export const renderWithState = (ui, options) => {
  return render(ui, { wrapper: StateProvider, ...options });
}
import { renderWithState } from '../path/to/utils';

...

it('loads component', () => {
  const { queryByRole } = renderWithState(<PlayerSelector />);
  expect(queryByRole('button')).toHaveAttribute('aria-label');
});