首页 > 解决方案 > 尝试使用 mount 进行测试时,React Enzyme setState 不起作用

问题描述

我正在尝试使用 Jest 和 Enzyme 在我的 React App 中测试此代码块:

  openDeleteUserModal = ({ row }: { row: IUser | null }): any => (
    event: React.SyntheticEvent
  ): void => {
    if (event) event.preventDefault();
    this.setState({ userToDelete: row, isDeleteUserModalOpen: true });
  };

这是测试:

    describe('OpenDeleteUserModal', () => {
      let wrapper: ReactWrapper;
      let instance: any;
      beforeEach(() => {
        wrapper = mount(
          <MemoryRouter>
            <Route render={props => <UsersOverviewScreen {...props} {...defaultProps} />} />
          </MemoryRouter>
        );
        instance = getComponentInstance(wrapper);
        instance.openDeleteUserModal({ user: mockUser });
        wrapper.update();
      });
      it('should SET the isDeleteUserModalOpen to true', () => {
        expect(instance.state.isDeleteUserModalOpen).toBeTruthy();
      });
      it('should SET the userToDelete to mockUser', () => {
        expect(instance.state.userToDelete).toEqual(mockUser);
      });
    });

测试和文件是.tsx,这意味着需要所有关于 React Router 的样板文件。我得到了错误,并且未定义而不是真实。

我试图模拟点击但没有运气。见下文:

      it('should SET the isDeleteUserModalOpen to true', () => {
        const deleteUserButton = wrapper.find('renderUsers').find('button');
        deleteUserButton.simulate('click');
        jest.spyOn(instance, 'openDeleteUserModal');
        instance.openDeleteUserModal();
        expect(instance.openDeleteUserModal).toHaveBeenCalled();
        expect(instance.state.isDeleteUserModalOpen).toBeTruthy();
      });

有人可以帮我理解为什么会失败。

标签: javascriptreactjstypescriptjestjsenzyme

解决方案


我正在通过酶 github样品酶测试。试试这个

describe('OpenDeleteUserModal', () => {
  let wrapper: ReactWrapper;
  let instance: any;
  beforeEach(() => {
    wrapper = mount(
      <MemoryRouter>
        <Route render={props => <UsersOverviewScreen {...props} {...defaultProps} />} />
      </MemoryRouter>
    );
    instance = getComponentInstance(wrapper);
    instance.openDeleteUserModal({ user: mockUser });
    // wrapper.update(); --don't think this is required but do check!
  });
  it('should SET the isDeleteUserModalOpen to true', () => {
    //expect(instance.state.isDeleteUserModalOpen).toBeTruthy();
    expect(wrapper.state('isDeleteUserModalOpen')).toBeTruthy();
  });
  it('should SET the userToDelete to mockUser', () => {
    //expect(instance.state.userToDelete).toEqual(mockUser);
    expect(wrapper.state('userToDelete')).toEqual(mockUser);
  });
});

这很可能是因为 setState() 是一个异步操作。当您的测试线运行时,相关状态可能尚未初始化。Enzyme 似乎为此提供了一个 API。

对于第二部分,这是 Enzyme 在测试箭头函数时的一个小警告。在这里查看我的答案。以下代码应该可以解决您的问题。

 it('should SET the isDeleteUserModalOpen to true', () => {
    const deleteUserButton = wrapper.find('renderUsers').find('button');
    deleteUserButton.simulate('click');

    //this returns an object which will record interactions on 'openDeleteUserModal'
    const spy = jest.spyOn(instance, 'openDeleteUserModal');
    //Force update on the component is required for the spy to 'latch onto' an arrow function
    instance.forceUpdate();

    instance.openDeleteUserModal();

    //You have to check your spy object not the instance method
    expect(spy).toHaveBeenCalled();

    expect(instance.state('isDeleteUserModalOpen')).toBeTruthy();
  });

推荐阅读