如何使用Jest / Enzyme测试React中的keydown事件?

时间:2019-11-07 12:01:29

标签: javascript reactjs jestjs enzyme

我有以下内容:

import React, { Component } from 'react';

export class Cars extends Component {
  constructor(props) {
    super(props);
    this.state = {
      activeSearch: true
    };
  }

  componentDidMount() {
    document.addEventListener('keydown', this.escFunction, false);
  }

  escFunction(event) {
    if (event.keyCode === 27) this.skipCar();
  }

  skipCar() {
    this.setState({ activeSearch: false });
  }

  render() {
    return <div></div>;
  }
}

我编写了以下测试来检查此函数是否被调用:

test('should close', () => {
    let events = {};
    document.addEventListener = jest.fn((event, cb) => {
      events[event] = cb;
    });

    const wrapper = shallow(<Cars {...props} />);
    const instance = wrapper.instance();
    const spy = jest.spyOn(instance, 'skipCar');

    events.keyDown({ keyCode: 27 });

    expect(spy).toHaveBeenCalled();
    expect(wrapper.state().activeSearch).toBe(false);
  });

但是当我运行此测试时,我出现了一个错误:

TypeError: events.keyDown is not a function

    > 82 |     events.keyDown({ keyCode: 27 });
         |            ^

为什么会有这个错误????如何运行此测试以检查方法是否运行?

2 个答案:

答案 0 :(得分:2)

您应该使用event.keydown({ keyCode: 27 }),然后您的代码才能正常工作。

这是您的代码的工作单元测试:

index.jsx

import React, { Component } from 'react';

export class Cars extends Component {
  constructor(props) {
    super(props);
    this.state = {
      activeSearch: true
    };
    this.escFunction = this.escFunction.bind(this);
  }

  componentDidMount() {
    document.addEventListener('keydown', this.escFunction, false);
  }

  escFunction(event) {
    if (event.keyCode === 27) this.skipCar();
  }

  skipCar() {
    this.setState({ activeSearch: false });
  }

  render() {
    return <div></div>;
  }
}

index.spec.jsx

import React from 'react';
import { shallow } from 'enzyme';
import { Cars } from './';

const props = {};

test('should close', () => {
  let events = {};
  document.addEventListener = jest.fn((event, cb) => {
    events[event] = cb;
  });

  const wrapper = shallow(<Cars {...props} />);
  const instance = wrapper.instance();
  const spy = jest.spyOn(instance, 'skipCar');

  events.keydown({ keyCode: 27 });

  expect(spy).toHaveBeenCalled();
  expect(wrapper.state().activeSearch).toBe(false);
});

单元测试结果:

 PASS  src/stackoverflow/58748367/index.spec.jsx (7.988s)
  ✓ should close (10ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.214s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58748367

答案 1 :(得分:0)

更好的方法不是模拟addEventListener,而是触发文档上的事件。

var event = new KeyboardEvent('keydown', {'keyCode': 37});
document.dispatchEvent(event);

这将使您模仿现实生活中的场景。

相关问题