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

时间:2018-01-12 11:21:39

标签: reactjs sinon enzyme jest

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

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

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)

如何编写一个测试,检查道具更新时是否调用了方法?谷歌搜索了几个小时,找不到任何文章/教程/帮助/问题。

不要犹豫,要求提供更多信息。谢谢!

2 个答案:

答案 0 :(得分:2)

你正在将一个罪孽间谍传递给一个期望一个Jest间谍的断言。 Jest内置的断言知道如何检查自己的嘲笑和间谍,但它不知道如何与其他图书馆的间谍做这件事

使用Jest间谍

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

直接断言sinon spy的属性

const spy = sinon.spy(VideoPlayer.prototype, 'togglePlayPause')
//...
expect(spy.calledOnce).toBe(true)

答案 1 :(得分:1)

from datetime import datetime, time

import pandas as pd
import numpy as np

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ohlc, candlestick_ohlc
import matplotlib.dates as mdates
from matplotlib import ticker

bar_df = generate_pseudo_data()
fig, ax = plt.subplots()
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()

candlestick2_ohlc(ax, bar_df.open, bar_df.high, bar_df.low, bar_df.close,
                  width=0.6, colorup='r', colordown='c', alpha=1)
xdate = bar_df.index
def mydate(x, pos):
    try:
        return xdate[int(x)]
    except IndexError:
        return ''

ax.xaxis.set_major_formatter(ticker.FuncFormatter(mydate))
# Everything works fine up to now.
# However the xticklabels are not exactly at 22:00, 23:00, etc.
# And no minor tick labels set up at 21:15, 21:30, 21:45, etc.

# I tried either one of the command below, but both failed with no xticklabels
# showed up.

ax.xaxis.set_major_locator(mdates.HourLocator())
ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0, 15, 30, 45],
                                                interval=1))

# This one works because it only tells xticklabels to have at most
# 8 tick labels, but no info about where the xticklabels should be.
ax.xaxis.set_major_locator(ticker.MaxNLocator(8))