Использование Jest для отслеживания вызова метода в компонентеDidMount

Недавно мне захотелось проверить, что какой-то пользовательский метод условно вызывается в методе componentDidMount компонента React.

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

Я использую Jest в качестве рамки тестирования, которая включает jest.fn() для mocks/spies. Я читал, что это было бы довольно тривиально для тестирования с Sinon, сделав что-то вроде следующего:

sinon.spy(Component.prototype, "methodName");
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();

Я пытаюсь воссоздать это с Jest так:

Component.prototype.methodName = jest.fn();
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();

Этот код выходит из строя и выдает следующую ошибку:

jest.fn() value must be a mock function or spy.
Received:
  function: [Function bound mockConstructor]

Можно ли проверить эту функциональность с помощью Jest? И если да, то как?

Ответ 1

Ключ использует метод jests spyOn. Должно быть так:

const spy = jest.spyOn(Component.prototype, 'methodName');
const wrapper = mount(<Component {...props} />);
wrapper.instance().methodName();
expect(spy).toHaveBeenCalled();

Как показано здесь, например: Проверьте, не вызвана ли функция реагирует и фермент

Обратите внимание, также рекомендуется очищать шпионскую функцию после каждого запуска теста

let spy

afterEach(() => {
  spy.mockClear()
})

https://facebook.github.io/jest/docs/en/jest-object.html#jestclearallmocks

Ответ 2

Я знаю, что уже немного поздно, но я столкнулся с этим и предложил бы, чтобы тест componentDidMount инициировал вызов вашего вложенного метода, чтобы ваш тест выглядел примерно так:

Модуль

componentDidMount() {
  if (this.props.initOpen) {
    this.methodName();
  }
}

Тест - Хорошо

it('should call methodName during componentDidMount', () => {
    const methodNameFake = jest.spyOn(MyComponent.prototype, 'methodName');
    const wrapper = mount(<MyComponent {...props} />);
    expect(methodNameFake).toHaveBeenCalledTimes(1);
});

Если вы вызываете componentDidMount, то утверждение о том, что methodName был вызван через componentDidMount, является более верным.

Тест - Плохо

it('should call methodName during componentDidMount', () => {
    const spy = jest.spyOn(Component.prototype, 'methodName');
    const wrapper = mount(<Component {...props} />);
    wrapper.instance().methodName();
    expect(spy).toHaveBeenCalled();
}

Написав такой тест, вы вызываете метод, а затем утверждаете, что он был вызван. Который, конечно, это даст вам только что назвал это.