admin管理员组

文章数量:1279241

Thats my ponent

class Foo extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            ...
        };

        this.input = React.createRef();
    }

    ponentDidMount() {
        const id = 'bar';
        let element = document.getElementById(id);
        element.addEventListener('transitionend', () => {
            this.setState({ ... });
        }, false);
    }

    ...

When I set up my test like so

import React from 'react';
import { mount } from 'enzyme';
import 'jsdom-global/register';

import Foo from './';

it('renders the ponent correctly', () => {
    const ponent = mount(
        <Foo />
    );

    ponent
        .unmount();
});

I get

console.error node_modules/react-dom/cjs/react-dom.development.js:16647 The above error occurred in the ponent: in Foo (created by WrapperComponent) in WrapperComponent

Consider adding an error boundary to your tree to customize error handling behavior. ● renders the ponent correctly TypeError: Cannot read property 'addEventListener' of null

I tried

ReactDOM.render(<Foo />, document.body);

or adding this

const map = {};
Window.addEventListener = jest.genMockFn().mockImpl((event, cb) => {
  map[event] = cb;
});

as well as this

const map = {};
    document.addEventListener = jest.fn((event, cb) => {
      map[event] = cb;
    })

before mounting <Foo /> in the test. But it all es back with the same error. Why is that?

Thats my ponent

class Foo extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            ...
        };

        this.input = React.createRef();
    }

    ponentDidMount() {
        const id = 'bar';
        let element = document.getElementById(id);
        element.addEventListener('transitionend', () => {
            this.setState({ ... });
        }, false);
    }

    ...

When I set up my test like so

import React from 'react';
import { mount } from 'enzyme';
import 'jsdom-global/register';

import Foo from './';

it('renders the ponent correctly', () => {
    const ponent = mount(
        <Foo />
    );

    ponent
        .unmount();
});

I get

console.error node_modules/react-dom/cjs/react-dom.development.js:16647 The above error occurred in the ponent: in Foo (created by WrapperComponent) in WrapperComponent

Consider adding an error boundary to your tree to customize error handling behavior. ● renders the ponent correctly TypeError: Cannot read property 'addEventListener' of null

I tried

ReactDOM.render(<Foo />, document.body);

or adding this

const map = {};
Window.addEventListener = jest.genMockFn().mockImpl((event, cb) => {
  map[event] = cb;
});

as well as this

const map = {};
    document.addEventListener = jest.fn((event, cb) => {
      map[event] = cb;
    })

before mounting <Foo /> in the test. But it all es back with the same error. Why is that?

Share Improve this question asked Feb 12, 2019 at 10:51 four-eyesfour-eyes 12.4k36 gold badges130 silver badges254 bronze badges 1
  • 1 Possible duplicate of jest + enzyme, using mount(), document.getElementById() returns null on ponent which appear after _method call – Agney Commented Feb 12, 2019 at 11:29
Add a ment  | 

1 Answer 1

Reset to default 5

One of reasons why direct DOM access is discouraged in React is because it makes testing more plicated and unpredictable.

DOM can be mocked entirely before mounting a ponent:

const elementMock = { addEventListener: jest.fn() };
jest.spyOn(document, 'getElementById').mockImplementation(() => elementMock);

A stub can be tested that is was called correctly:

expect(elementMock.addEventListener).toBeCalledWith('transitionend', expect.any(Function), false);

And event listener can be tested that it changes the state as expected:

const handler = elementMock.mock.calls[0][1];
handler();
...

本文标签: javascriptHow to mock eventListener when set in componentDidMount()Stack Overflow