【问题标题】:How to assert a function is called from within another function?如何断言一个函数是从另一个函数中调用的?
【发布时间】:2017-12-19 13:15:10
【问题描述】:

我在 React 中有一个带有 onChange 事件的组件。在下面的代码中,我需要断言当

时调用了正确的方法
this.props.onChangeImage()

在图库组件中调用。

export class Form extends React.PureComponent {

  componentDidMount = () => {
    this.props.getUser();
    this.props.getImages();
    this.props.getBoards();
  }

  render() {
    if (this.props.pin === null) {
      let boards = [];
      boards = this.props.boards;
      boards = boards.data.map(
        (item) => <MenuItem key={item.id.toString()} value={item.name} primaryText={item.name} />
      );
      return (
        <div>
          <Helmet
            title="Form"
            meta={[
              { name: 'description', content: 'Description of Form' },
            ]}
          />
          <Gallery images={this.props.images} onChange={this.props.onChangeImage} />
        </div>
      );
    }
    return (<div className="spinner-container"><CircularProgress /></div>);
  }
}

下面,在 onChangeImage 方法中,我试图断言调用了 sendEventToParentWindow 方法。

function mapDispatchToProps(dispatch) {
  return {

    onChangeImage: (event) => {
      dispatch(createPinImage(event.target.value));
      sendEventToParentWindow({
        action: 'change-image',
        description: 'Change image',
      });
    },
  };
}

function sendEventToParentWindow(message) {
  window.postMessage(message, window.location.href);
}

export default connect(mapStateToProps, mapDispatchToProps)(Form);

我在这里查看了许多答案,虽然这个似乎最接近,但它并没有让我到达那里:Jest - mocking a function call

编辑:这是我的测试,我认为这是错误的,因为它分配模拟函数以直接调用 onChange,而实际上它应该调用反过来调用模拟的函数。我需要以某种方式调用 onImageChange 函数,然后验证是否调用了我的间谍。

import Gallery from '../index';
import * as formIndex from '../../../containers/Form';

describe('<Gallery />', () => {
  it('Expect sendMessageToParentWindow to be called on image change', () => {
    const sendEventToParentWindowMock = jest.spyOn(formIndex, 'sendEventToParentWindow');
    const gallery = shallow(<Gallery images={imagesMockData} onChange={sendEventToParentWindowMock} />);
    gallery.find('input#image-1').simulate('change');

    expect(sendEventToParentWindowMock).toBeCalled();
  });
}

【问题讨论】:

  • 您使用的是哪个测试库?酶?如果是,那么您是否对组件进行了浅层渲染?
  • @HardikModha,我确实有 Enzyme 可用,并尝试过浅渲染和安装组件。我没有任何运气,但我仍在学习和修补。感谢您的提示!
  • 在浅层渲染组件时,可以将模拟函数(其实现包含模拟方法调用)作为道具传递。
  • @HardikModha 这似乎成功了。我真的很接近这个问题,但还没有完全解决。谢谢!我正在用其他一些组件构建一些测试,如果我有任何其他问题,我会回复。如果一切顺利,我会发布我的答案。再次感谢!
  • 很高兴它对您有所帮助。 :)

标签: javascript reactjs unit-testing jestjs frontend


【解决方案1】:

正如我在评论中提到的,您可以将模拟函数作为 prop 传递,其实现将包含对您的 sendEventToParentWindow 函数的调用。即您需要创建两个模拟函数。

  1. sendEventToParentWindow 模拟函数。
  2. onChangeImage 带有实现的模拟函数,其中实现将只包含对您的 sendEventToParentWindow 模拟函数的调用。

所以测试看起来像这样,

describe('<Gallery />', () => {
  it('Expect sendMessageToParentWindow to be called on image change', () => {
    const sendEventToParentWindowMock = jest.fn();
    const onChangeImageMock = jest.fn(() => {
         sendEventToParentWindowMock();
    });

    const gallery = shallow(<Gallery images={imagesMockData} onChange={onChangeImageMock} />); // Passing the mocked onChangeImage as prop
    gallery.find('input#image-1').simulate('change');

    expect(sendEventToParentWindowMock).toBeCalled();
  });
}

希望对你有帮助:)

【讨论】:

  • 这就是我所缺少的理解!我会在星期一回到办公室时尝试一下,但再次感谢您的耐心和示例代码!能够看到一个可靠的例子真的很有帮助。
  • 那是缺失的部分!再次感谢。我已经接受了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
  • 2019-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
相关资源
最近更新 更多