代码之家  ›  专栏  ›  技术社区  ›  jorgen

使用react测试库测试react热键

  •  0
  • jorgen  · 技术社区  · 7 年前

    https://github.com/greena13/react-hotkeys

    https://github.com/kentcdodds/react-testing-library

    import React from 'react';
    import { HotKeys } from 'react-hotkeys';
    
    class TestComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = { enterClicked: false };
      }
    
      render() {
        const { enterClicked } = this.state;
        return (
          <HotKeys
            handlers={{
              enter: (e) => {
                console.log('ENTER', e);
                this.setState({ enterClicked: true });
              },
            }}
          >
            <input placeholder="input" type="text" />
            {enterClicked && <div>Enter clicked</div>}
          </HotKeys>
        );
      }
    }
    
    export default TestComponent;
    

    下面是一个测试:

    import React from 'react';
    import { cleanup, fireEvent, render, waitForElement } from 'react-testing-library';
    
    import TestComponent from './TestComponent';
    
    afterEach(cleanup);
    
    describe('Test', () => {
      it('Hotkeys', () => {
        const { debug, getByPlaceholderText, getByText } = render(<TestComponent />);
        const inputNode = getByPlaceholderText('input');
        fireEvent.keyDown(inputNode, { key: 'Enter', keyCode: 13, code: 13, bubbles: true });
        debug();
        waitForElement(() => getByText('Enter clicked'));
      });
    });
    

    以下是我的jest设置文件:

    /* global jest */
    import { JSDOM } from 'jsdom';
    import 'jest-localstorage-mock';
    import dotenv from 'dotenv';
    
    dotenv.config({ path: '../.env' });
    
    const jsdom = new JSDOM('<!doctype html><html><body></body></html>', { url: 'https://example.com' });
    const { window } = jsdom;
    window.location.reload = jest.fn();
    window.location.assign = jest.fn();
    
    function copyProps(src, target) {
      const props = Object.getOwnPropertyNames(src)
        .filter((prop) => typeof target[prop] === 'undefined')
        .reduce(
          (result, prop) => ({
            ...result,
            [prop]: Object.getOwnPropertyDescriptor(src, prop),
          }),
          {},
        );
      Object.defineProperties(target, props);
    }
    
    if (!window.attachEvent) {
      // eslint-disable-next-line func-names
      const attachEvent = function(on, callback) {
        on = on.substring(2, on.length);
        return this.addEventListener(on, callback);
      };
    
      window.Element.prototype.attachEvent = attachEvent;
    }
    
    if (!window.detachEvent) {
      // eslint-disable-next-line func-names
      const detachEvent = function(on, callback) {
        on = on.substring(2, on.length);
        return this.removeEventListener(on, callback);
      };
    
      window.Element.prototype.detachEvent = detachEvent;
    }
    
    global.window = window;
    global.document = window.document;
    global.navigator = {
      userAgent: 'node.js',
      platform: 'Mac',
    };
    copyProps(window, global);
    
    global.fetch = require('jest-fetch-mock');
    
    global.requestAnimationFrame = (cb) => {
      setTimeout(cb, 0);
    };
    
    global.cancelAnimationFrame = (cb) => {
      setTimeout(cb, 0);
    };
    

    有什么想法吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   jorgen    7 年前

    以下是我是如何做到这一点的:

    HotKeys

    <HotKeys
      data-testid="hot-keys-id"
      ...
    

    然后我聚焦组件,然后手动创建一个事件:

    const hotkeys = await waitForElement(() => getByTestId('hot-keys-id'));
    hotkeys.focus();
    
    const keyDownEvent = new Event('keydown');
    keyDownEvent.keyCode = 13;
    keyDownEvent.key = 'Enter';
    keyDownEvent.code = 13;
    
    hotkeys.dispatchEvent(keyDownEvent);