jsdom: dispatchEvent / addEventListener scheint nicht zu funktionieren

Zusammenfassung

Ich versuche, eine React-Komponente zu testen, die native DOM-Ereignisse in ihremcomponentWillMount.

Ich finde, dass jsdom @8.4.0) funktioniert beim Versenden von Ereignissen und Hinzufügen von Ereignis-Listenern nicht wie erwartet.

Das einfachste Stück Code, das ich extrahieren kann:

window.addEventListener('click', () => {
  throw new Error("success")
})

const event = new Event('click')
document.dispatchEvent(event)

throw new Error('failure')

Dies wirft "Fehler".

Kontext

Auf das Risiko, dass das oben Genannte ein @ iXY Problem, Ich möchte mehr Kontext bereitstellen.

Hier ist eine extrahierte / vereinfachte Version der Komponente, die ich testen möchte.Sie können sehen, dass es auf dem Webpackbin funktioniert.

import React from 'react'

export default class Example extends React.Component {
  constructor() {
    super()
    this._onDocumentClick = this._onDocumentClick.bind(this)
  }

  componentWillMount() {
    this.setState({ clicked: false })
    window.addEventListener('click', this._onDocumentClick)
  }

  _onDocumentClick() {
    const clicked = this.state.clicked || false
    this.setState({ clicked: !clicked })
  }


  render() {
    return <p>{JSON.stringify(this.state.clicked)}</p>
  }
}

Hier ist der Test, den ich zu schreiben versuche.

import React from 'react'
import ReactDOM from 'react-dom'
import { mount } from 'enzyme'

import Example from '../src/example'

describe('test', () => {
  it('test', () => {
    const wrapper = mount(<Example />)

    const event = new Event('click')
    document.dispatchEvent(event)

    // at this point, I expect the component to re-render,
    // with updated state.

    expect(wrapper.text()).to.match(/true/)
  })
})

Nur der Vollständigkeit halber, hier ist meintest_helper.js was jsdom initialisiert:

import { jsdom } from 'jsdom'
import chai from 'chai'

const doc = jsdom('<!doctype html><html><body></body></html>')
const win = doc.defaultView

global.document = doc
global.window = win

Object.keys(window).forEach((key) => {
  if (!(key in global)) {
    global[key] = window[key]
  }
})

Reproduktionsfall:

Ich habe einen Repro-Fall hier:https: //github.com/jbinto/repro-jsdom-events-not-firin

git clone https://github.com/jbinto/repro-jsdom-events-not-firing.git cd repro-jsdom-events-not-firing npm install npm test

Antworten auf die Frage(6)

Ihre Antwort auf die Frage