尝试使用mount进行测试时,React Enzyme setState不起作用

时间:2019-04-09 08:06:14

标签: javascript reactjs typescript jestjs enzyme

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

[XmlRoot(ElementName = "SalesOrders", Namespace = "")]
public class MyArbitraryName
{
    [XmlElement("SalesOrder")]
    public List<SalesOrder> Orders { get; set; }
}

public class SalesOrder 
{
    public int Id{get;set;}
}

这是测试:

  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); }); }); ,这意味着需要与React Router有关的所有样板。我返回的是false,并且是undefined而不是true。

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

.tsx

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

2 个答案:

答案 0 :(得分:1)

我正在经历酶github sample enzyme tests。试试看

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()是异步操作。当你的   测试行运行的相关状态可能尚未初始化。   酶似乎为此提供了一个API。

对于第二部分,这是测试箭头功能时酶的一个小警告。签出我的答案here。以下代码可以解决您的问题。

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

答案 1 :(得分:0)

我来这里是为了寻找解决方案,但是,提供的答案对我不起作用。在咨询了 Enzyme doc 后,发现 setState() 对我来说很好用。下面是我的解决方案,使用 setState(),我们不需要调用 Update(),因为 setState() 会重新渲染组件。

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