React:如何测试更新道具时是否调用了方法?

React: how to test if method is called when updating props?

我正在尝试编写一个测试来检查在更新组件的 props 时是否调用了一个方法。

这是组件(删除了不必要的东西):

import React from 'react';
import styled from 'styled-components';

const Video = styled.video`
  display: block;
  width: 100%;
`;

export default class VideoPlayer extends React.Component {
  componentWillReceiveProps(nextProps) {
    if (this.props.isPaused !== nextProps.isPaused) {
      this.togglePlayPause(nextProps.isPaused);
    }
  }

  togglePlayPause(isPaused) {
    if (isPaused) {
      this.video.pause();
    } else {
      this.video.play();
    }
  }

  render() {
    return (
      <Video />
    );
  }
}

这是我写的测试:

import React from 'react';
import Enzyme, { mount } from 'enzyme';
import renderer from 'react-test-renderer';
import Adapter from 'enzyme-adapter-react-16';
import 'jest-styled-components';
import sinon from 'sinon';
import VideoPlayer from './../src/app/components/VideoPlayer/VideoPlayer';

Enzyme.configure({ adapter: new Adapter() });

test('Checks if togglePlayPause gets called', () => {
  const spy = sinon.spy(VideoPlayer.prototype, 'togglePlayPause');
  const Component = mount(<VideoPlayer videoURL="http://localhost:3001/vid/local-video.mp4" volume={100} isPaused={false} />);

  Component.setProps({ isPaused: true });
  expect(spy).toBeCalled();
});

但是,当我 运行 这个测试时,我得到以下错误:

expect(jest.fn())[.not].toBeCalled()

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

  21 |
  22 |   Component.setProps({ isPaused: true });
> 23 |   expect(spy).toBeCalled();
  24 | });
  25 |

  at Object.<anonymous> (__tests__/VideoPlayer.react-test.js:23:15)

我如何编写一个测试来检查在 props 更新时是否调用了一个方法?谷歌搜索了几个小时了,找不到任何关于此的 articles/tutorials/help/issues。

请随时询问更多信息。谢谢!

您正在将 sinon 间谍传递给需要 Jest 间谍的断言。 Jest 的内置断言知道如何检查它自己的模拟和间谍,但它不知道如何使用来自另一个库的间谍来做到这一点

要么使用 Jest 间谍

const spy = jest.spyOn(VideoPlayer.prototype, 'togglePlayPause')
//...
expect(spy).toBeCalled()

或者直接断言 sinon 间谍的属性

const spy = sinon.spy(VideoPlayer.prototype, 'togglePlayPause')
//...
expect(spy.calledOnce).toBe(true)
const createTestFunction = (yourCheckFunction) => {
  let amountOfCalls = 0;
  const testFunction = function() {
    amountOfCalls++;
    return yourCheckFunction.apply(this, arguments);
  };

  testFunction.getCalls = (() => amountOfCalls);

  return testFunction;
}

const testabelFunction = createTestFunction(Math.max);

testabelFunction.getCalls(); // 0

testabelFunction(1, 3, 2) // Math.max(1,3,2) -> 3

testabelFunction.getCalls(); // 1