首页 > 解决方案 > 如何测试 React 状态是否从 localStorage 重新加载?

问题描述

我使用 Jest 和 Enzyme 来测试组件,但在重新加载时遇到了问题。我希望我的组件从 localStorage 中检索状态。我还没有实现代码,但测试仍然通过。

  it('can preserve todo group', () => {
    const wrapper = mount(<TodosContainer />);
    wrapper.find('input[name="todo-container-form"]').simulate('change', { target: { value: 'Loy' } });
    wrapper.find('button').simulate('click');
    // eslint-disable-next-line no-undef
    window.location.reload();
    /* This is where it should fail without implementation
    I didn't add any localStorage code in my component. */
    expect(wrapper.find(TodosGroup).first().prop('name')).toMatch('Loy');
  });

这是我的组件,其中不相关的部分已被编辑。

const TodosContainer = () => {
  const [todosGroups, setTodosGroups] = useState([]);
  const [groupName, setGroupName] = useState('');
  const [errorMessage, setErrorMessage] = useState('');
  const addTodoGroups = (todoGroup: ITodoGroup) => {
    setTodosGroups([...todosGroups, todoGroup]);
  };
  const changeName = (e: React.ChangeEvent<HTMLInputElement>) => {
    setGroupName(e.target.value);
  };
  const handleClick = () => {
    if (groupName.length > 0) {
      addTodoGroups({ name: groupName, key: Date.now() });
      setGroupName('');
      setErrorMessage('');
    } else {
      setErrorMessage('Group name must not be empty');
    }
  };
  return (
    <div    >
      <div      >
        {errorMessage.length > 0 ? <ErrorMessage css={css`width: 100%`}>{errorMessage}</ErrorMessage> : ''}
        <TextInput name="todo-container-form" className="todoGroupName" value={groupName} onChange={changeName} />
        <Button type="button" onClick={handleClick}>Add</Button>
      </div>
      {todosGroups.length > 0 ? todosGroups.map((todoGroup) => (
        <div
          key={todoGroup.key}
        >
          <TodosGroup name={todoGroup.name} />
        </div>
      )) : (
        <p>
        No todos group
        </p>
      )}
    </div>
  );

};

export default TodosContainer;

标签: javascriptreactjsjestjslocal-storage

解决方案


因为 jest 使用 JSDo 而不是真正的浏览器window.location.reload();什么都不做。另外我担心 jsdom 也没有实现localStorage(但很容易模拟

您想确保在重新创建组件后,它会从本地存储中获取状态,对吗?

这样(在适当的模拟之后localStorage)你可以卸载组件并再次安装它:

wrapper.unmount();
const newOne = mount(<TodosContainer />);
expect(newOne.find(TodosGroup).first().prop('name')).toMatch('Loy');

这里不需要显式卸载,但我宁愿让它完全模拟条件(例如,它会运行componentWillUnmount/useEffect可能是逻辑的一部分)。


推荐阅读