Как выполнить модульное тестирование componentDidMount, используя jest / энзим, когда Component.prototype возвращает undefined? - PullRequest
0 голосов
/ 16 января 2020

Я пытаюсь написать простой тест, чтобы увидеть, вызывается ли componentDidMount в компоненте HomePage ниже:

class HomePage extends Component {
  state = {...}
  async componentDidMount(){
    // a couple of if conditions and an ajax request
  }
}

Для теста я пытаюсь выполнить следующее, чтобы увидеть, Компонент componentDidMount вызывается:

describe('<Homepage/>', () => {
  let props, store, mockStore, initialState

  beforeEach(() => {
    props = {
      getPoints: jest.fn(),
      estimatePoints: jest.fn()
    }
    initialState = {
      homeReducer: {
        profile: {}
      },
      pointsReducer: {
        score: {
          points: {}
        }
      }
    }

    mockStore = configureStore()
    store = mockStore(initialState)
  })

  it('should call the componentDidMount lifecycle method', () => {
    const spy = jest.spyOn(HomePage.prototype, 'componentDidMount')
    const wrapper = mount(
      <Provider store={store}>
        <HomePage {...props}/>
      </Provider>
    )
    expect(spy).toHaveBeenCalled()
    wrapper.unmount()
  })
})

Я получаю ошибку Cannot spyOn on a primitive value; undefined given. Я тоже пытался использовать shallow и wrapper.instance(), но безуспешно. Каков будет правильный способ проверки componentDidMount в этом случае?

1 Ответ

1 голос
/ 20 января 2020

Я уверен, что вы используете connect HO C из react-redux обернутого компонента реакции HomePage. Вам нужно использовать свойство WrappedComponent stati c, чтобы получить исходный компонент реакции. Затем вы можете следить за ним.

Краткий ответ:

const spy = jest.spyOn(HomePage.WrappedComponent.prototype, 'componentDidMount');

Завершенный рабочий пример:

index.tsx:

import React, { Component } from 'react';
import { connect } from 'react-redux';

export class HomePage extends Component {
  state = {};
  async componentDidMount() {
    console.log('a couple of if conditions and an ajax request');
  }

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

export default connect()(HomePage);

index.test.tsx:

import HomePage from './';
import configureStore from 'redux-mock-store';
import { mount } from 'enzyme';
import React from 'react';
import { Provider } from 'react-redux';

describe('<Homepage/>', () => {
  let props, store, mockStore, initialState;

  beforeEach(() => {
    props = {
      getPoints: jest.fn(),
      estimatePoints: jest.fn(),
    };
    initialState = {
      homeReducer: {
        profile: {},
      },
      pointsReducer: {
        score: {
          points: {},
        },
      },
    };

    mockStore = configureStore();
    store = mockStore(initialState);
  });

  it('should call the componentDidMount lifecycle method', () => {
    const spy = jest.spyOn(HomePage.WrappedComponent.prototype, 'componentDidMount');
    const wrapper = mount(
      <Provider store={store}>
        <HomePage {...props} />
      </Provider>,
    );
    expect(spy).toHaveBeenCalled();
    wrapper.unmount();
  });
});

Результаты модульных испытаний:

 PASS  src/stackoverflow/59759511/index.test.tsx (9.85s)
  <Homepage/>
    ✓ should call the componentDidMount lifecycle method (62ms)

  console.log src/stackoverflow/59759511/index.tsx:7
    a couple of if conditions and an ajax request

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

Исходный код: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59759511

...