【问题标题】:How to mock keypress event on Window object with Enzyme / Jest?如何使用 Enzyme / Jest 在 Window 对象上模拟按键事件?
【发布时间】:2022-02-07 15:36:33
【问题描述】:

我正在寻找一种方法来测试我的 React 组件钩子:

export default function useKeyUp(key: Key, onKeyUp: Function) {
    useEffect(() => {

        const handleUp = (event: KeyboardEvent) => {
            const { key: releasedKey } = event
            if (key === releasedKey) {
                if (onKeyUp) {
                    onKeyUp()
                }
            }
        }

        window.addEventListener('keyup', handleUp)

        return () => {
            window.removeEventListener('keyup', handleUp)
        }
    }, [key, onKeyUp])
}

如何在 Jest / Enzyme 中模拟 / 模拟在 Window 对象上触发的事件?

【问题讨论】:

    标签: reactjs typescript unit-testing jestjs enzyme


    【解决方案1】:

    因为enzyme 不能像react-hooks-testing-library 那样直接测试反应钩子。我们可以在组件内部使用钩子。然后,使用mount 渲染组件。

    使用keyboardEvent 构造函数创建一个“keyup”事件并通过dispatchEvent Web API 调度该事件。

    例如

    useKeyUp.ts:

    import { useEffect } from 'react';
    
    type Key = string;
    export default function useKeyUp(key: Key, onKeyUp: Function) {
      useEffect(() => {
        const handleUp = (event: KeyboardEvent) => {
          const { key: releasedKey } = event;
          if (key === releasedKey) {
            if (onKeyUp) {
              onKeyUp();
            }
          }
        };
    
        window.addEventListener('keyup', handleUp);
    
        return () => {
          window.removeEventListener('keyup', handleUp);
        };
      }, [key, onKeyUp]);
    }
    

    useKeyUp.test.tsx:

    import { mount } from 'enzyme';
    import React from 'react';
    import useKeyUp from './useKeyUp';
    
    describe('70938281', () => {
      test('should call onKeyUp callback', () => {
        const mOnKeyUp = jest.fn();
        function TestComp() {
          useKeyUp('s', mOnKeyUp);
          return null;
        }
        const wrapper = mount(<TestComp />);
        const keyUpEvent = new KeyboardEvent('keyup', { key: 's' });
        window.dispatchEvent(keyUpEvent);
        expect(mOnKeyUp).toBeCalledTimes(1);
        wrapper.unmount();
        window.dispatchEvent(keyUpEvent);
        expect(mOnKeyUp).toBeCalledTimes(1);
      });
    
      test('should NOT call onKeyUp callback', () => {
        const mOnKeyUp = jest.fn();
        function TestComp() {
          useKeyUp('s', mOnKeyUp);
          return null;
        }
        mount(<TestComp />);
        const keyUpEvent = new KeyboardEvent('keyup', { key: 'a' });
        window.dispatchEvent(keyUpEvent);
        expect(mOnKeyUp).not.toBeCalled();
      });
    });
    

    测试结果:

     PASS  stackoverflow/70938281/useKeyUp.test.tsx (8.484 s)
      70938281
        ✓ should call onKeyUp callback (29 ms)
        ✓ should NOT call onKeyUp callback (2 ms)
    
    -------------|---------|----------|---------|---------|-------------------
    File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -------------|---------|----------|---------|---------|-------------------
    All files    |     100 |       75 |     100 |     100 |                   
     useKeyUp.ts |     100 |       75 |     100 |     100 | 9                 
    -------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        8.937 s
    

    jest.config.js:

    module.exports = {
      preset: 'ts-jest/presets/js-with-ts',
      testEnvironment: 'enzyme',
      setupFilesAfterEnv: ['jest-enzyme', 'jest-extended'],
      setupFiles: ['./jest.setup.js'],
      testEnvironmentOptions: {
        enzymeAdapter: 'react16',
      },
    };
    

    【讨论】:

      猜你喜欢
      • 2019-10-27
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 2019-05-25
      • 1970-01-01
      • 2021-07-08
      • 2017-12-18
      • 1970-01-01
      相关资源
      最近更新 更多