【问题标题】:How to make a substitute function in a functional component jest enzyme如何在功能性成分酶中产生替代功能
【发布时间】:2021-05-25 10:39:11
【问题描述】:

开玩笑,我想检查函数是否被调用,以及调度方法是否在我的功能组件中被调用。我无法创建 spy 函数,因为它是一个函数组件,我无权访问实例对象。

import React, { Component } from 'react';
import { useDispatch } from 'react-redux';
import styles from './style.module.scss';

const AddTask = () => {
  const dispatch = useDispatch();
  const handleKeyDown = (e) => {
    const trimmedText = e.target.value.trim();
    if (e.which === 13 && trimmedText) {
      dispatch({ type: 'todoAdd', payload: trimmedText });
      e.target.value = '';
    }
  };

  return (
    <div className={styles.container}>
      <span className={styles.arrow} />
      <input
        className='new-todo'
        placeholder='What needs to be done?'
        onKeyDown={handleKeyDown}
      />
    </div>
  );
};

export default AddTask;


import { shallow } from 'enzyme';
import React from 'react';
import { useDispatch } from 'react-redux';
import AddTask from './AddTask';

jest.mock('react-redux');
let wrapper;

describe('Task:', () => {
  beforeEach(() => {
    wrapper = shallow(<AddTask />);
  });

  it('snapshot', () => {
    expect(wrapper).toMatchSnapshot();
  });

  it('called dispatch', () => {
    expect(useDispatch).toBeCalled(0);
  });
  it('called handleKeyDown fn', () => {
    wrapper.find('input').props().onKeyDown({ key: 'Enter' });
    const onKeyDown = jest.fn();
    expect(onKeyDown).toBeCalled();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Component Test

【问题讨论】:

    标签: reactjs redux jestjs react-hooks enzyme


    【解决方案1】:

    您应该只模拟useDispatch 钩子,使用jest.requireActual(moduleName) 方法要求不模拟原始模块。

    另外,你最好使用.simulate(event[, mock]) => Self方法来模拟包装器中节点上的事件。

    最后,使用jest.resetAllMocks() 重置所有模拟。

    例如

    AddTask.tsx:

    import React from 'react';
    import { useDispatch } from 'react-redux';
    
    const AddTask = () => {
      const dispatch = useDispatch();
    
      const handleKeyDown = (e) => {
        const trimmedText = e.target.value.trim();
        if (e.which === 13 && trimmedText) {
          dispatch({ type: 'todoAdd', payload: trimmedText });
          e.target.value = '';
        }
      };
    
      return (
        <div>
          <input className="new-todo" placeholder="What needs to be done?" onKeyDown={handleKeyDown} />
        </div>
      );
    };
    
    export default AddTask;
    

    AddTask.test.tsx:

    import { shallow, ShallowWrapper } from 'enzyme';
    import React from 'react';
    import { useDispatch } from 'react-redux';
    import AddTask from './AddTask';
    
    const mDispatch = jest.fn();
    
    jest.mock('react-redux', () => {
      const originalModule = jest.requireActual('react-redux');
      return {
        ...originalModule,
        useDispatch: jest.fn(() => mDispatch),
      };
    });
    
    describe('Task:', () => {
      let wrapper: ShallowWrapper;
      beforeEach(() => {
        wrapper = shallow(<AddTask />);
      });
      afterAll(() => {
        jest.resetAllMocks();
      });
    
      it('called handleKeyDown fn', () => {
        wrapper.find('input').simulate('keydown', { which: 13, target: { value: 'teresa teng' } });
        expect(useDispatch).toBeCalledTimes(1);
        expect(mDispatch).toBeCalledWith({ type: 'todoAdd', payload: 'teresa teng' });
      });
    });
    

    单元测试结果:

     PASS  examples/66328381/AddTask.test.tsx
      Task:
        ✓ called handleKeyDown fn (7 ms)
    
    -------------|---------|----------|---------|---------|-------------------
    File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -------------|---------|----------|---------|---------|-------------------
    All files    |     100 |       75 |     100 |     100 |                   
     AddTask.tsx |     100 |       75 |     100 |     100 | 9                 
    -------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        3.766 s, estimated 4 s
    

    【讨论】:

    • 谢谢。是工作。但我有 1 个错误“jest.mock() 的模块工厂不允许引用任何超出范围的变量。”我将 mDispatch 重命名为 mockDispatch 并且它可以正常工作。
    猜你喜欢
    • 2019-02-27
    • 2015-05-29
    • 2019-01-16
    • 2019-06-08
    • 2018-09-20
    • 2016-03-21
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    相关资源
    最近更新 更多