Как проверить событие keydown в React с помощью Jest / Enzyme? - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть следующий компонент:

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 ]

2 голосов
/ 08 ноября 2019

Вы должны использовать 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

0 голосов
/ 08 ноября 2019

Лучшим подходом является не насмешка addEventListener, а запуск события в документе.

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

Это позволит вам имитировать сценарий из реальной жизни.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...