【问题标题】:Testing click event in enzyme on react functional component not passing在反应功能组件上测试酶中的点击事件未通过
【发布时间】:2020-06-04 19:38:51
【问题描述】:

我正在尝试编写一个测试,以测试我的按钮何时被单击,handleClick 函数将被调用,但我在测试的断言中一直收到错误消息。 这是 React 组件:

function Profile() {

    const [name, setName] = useState({
        firstName: '',
        lastName: ''
    });
    const [names, setNames] = useState([]);

    const handleClick = (e) => {
        e.preventDefault();
        names.push(name);
    }

    return ( 
       <form >
        <input 
          type = "text"
          value = {name.firstName}
          onChange = {
            e => setName({
                ...name,
                firstName: e.target.value
            })
        }/> 
        <input 
          type = "text"
          value = {name.lastName}
          onChange = {
            e => setName({
                ...name,
                lastName: e.target.value
            })
        }/> 
        <button onClick = {handleClick} > Add Name < /button> </form>
    )
}
export default Profile

这是测试:

it('test 1 - call handleClick spy', () => {
  const handleClick = sinon.spy();
  let wrapper = shallow(<Profile handleClick={handleClick}/>);  
  wrapper.find('button').simulate('click',{preventDefault:()=>{}});
  expect(handleClick.calledOnce).toBe(true); 
  }); 

【问题讨论】:

    标签: javascript reactjs unit-testing jestjs enzyme


    【解决方案1】:

    点击事件不会触发你传入的模拟的handleClick方法,而是触发组件内部定义的handleClick方法。这就是为什么不调用模拟的 handleClick 方法的原因。

    要判断是否调用了组件内部的handleClick方法,可以使用preventDefault等间接方法判断是否调用了preventDefault函数。

    例如

    index.jsx:

    import React, { useState } from 'react';
    
    function Profile() {
      const [name, setName] = useState({
        firstName: '',
        lastName: '',
      });
      const [names, setNames] = useState([]);
    
      const handleClick = (e) => {
        e.preventDefault();
        names.push(name);
      };
    
      return (
        <form>
          <input
            type="text"
            value={name.firstName}
            onChange={(e) =>
              setName({
                ...name,
                firstName: e.target.value,
              })
            }
          />
          <input
            type="text"
            value={name.lastName}
            onChange={(e) =>
              setName({
                ...name,
                lastName: e.target.value,
              })
            }
          />
          <button onClick={handleClick}> Add Name </button>{' '}
        </form>
      );
    }
    export default Profile;
    

    index.test.jsx:

    import React from 'react';
    import Profile from '.';
    import { shallow } from 'enzyme';
    
    describe('62202833', () => {
      it('should pass', () => {
        const wrapper = shallow(<Profile></Profile>);
        const mEvent = { preventDefault: jest.fn() };
        wrapper.find('button').simulate('click', mEvent);
        expect(mEvent.preventDefault).toBeCalledTimes(1);
      });
    });
    

    单元测试结果:

     PASS  stackoverflow/62202833/index.test.jsx (13.273s)
      62202833
        ✓ should pass (12ms)
    
    -----------|---------|----------|---------|---------|-------------------
    File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -----------|---------|----------|---------|---------|-------------------
    All files  |   85.71 |      100 |      50 |      80 |                   
     index.jsx |   85.71 |      100 |      50 |      80 | 21-31             
    -----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        15.05s
    

    【讨论】:

    • 这个解决方案效果很好,谢谢。如果我没有 preventDefault 事件,我将如何测试?
    • Functional Components 在 React 16+ 中没有实例,因此您无法获取直接测试的方法。一种可能的测试策略是模拟两个输入框的更改,这将更新状态中的名称属性,然后模拟单击事件。然后,您可以为您的包装器声明 state.names 的值。
    • 这个解决方案对我不起作用。我问了一个单独的问题stackoverflow.com/questions/66674051/…@slideshowp2 有什么帮助吗?
    猜你喜欢
    • 2018-08-24
    • 1970-01-01
    • 2020-01-14
    • 2020-11-17
    • 2017-08-16
    • 2018-01-17
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多