javascript - 当在 react 组件中作为 Prop 传递时,如何模拟函数并测试它们是否被调用?

标签 javascript unit-testing reactjs jestjs

我正在关注此 stackoverflow 答案中的示例 - Test a React Component function with Jest .我有一个示例组件和测试设置。该组件在加载到 App.js 中时可以正常工作。

组件 -

import React, { PropTypes, Component } from 'react';

export default class ExampleModule extends Component {
  static propTypes = {
    onAction: PropTypes.func,
  }

  static defaultProps = {
  onAction: () => { console.log("In onAction"); }
}

doAction = () => {
  // do something else
  console.log('In do action');
  this.props.onAction();
}

render() {
  return(
    <div>
      <button className='action-btn' onClick=  {this.doAction.bind(this)}>Do action</button>
    </div>
  )
}
}

这是测试 -

import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import ExampleComponent from './ExampleModule.js';

let Example;

describe('Example component', function() {
  beforeEach(function() {
    Example = TestUtils.renderIntoDocument(<ExampleComponent />);
  })

  it('calls props functions', function() {
    Example.doAction = jest.genMockFunction();
    let actionBtn = TestUtils.findRenderedDOMComponentWithClass(Example, 'action-btn');
    TestUtils.Simulate.click(actionBtn);
    expect(Example.doAction).toBeCalled();
  })

  it('doAction calls onAction', function() {
    expect(Example.props.onAction).not.toBeCalled();
    Example.doAction();
    expect(Example.props.onAction).toBeCalled();
  })
})

但是,我收到以下错误 -

FAIL  src/App/components/Example/ExampleModule.test.js
  Console

    console.log src/App/components/Example/ExampleModule.js:14
      In do action
    console.log src/App/components/Example/ExampleModule.js:24
      In onAction

  Example component › calls props functions

    Expected the mock function to be called.

      at Object.<anonymous> (src/App/components/Example/ExampleModule.test.js:17:30)
      at process._tickCallback (node.js:369:9)

  Example component › doAction calls onAction

    toBeCalled matcher can only be used on a spy or mock function.

      at Object.<anonymous> (src/App/components/Example/ExampleModule.test.js:21:40)
      at process._tickCallback (node.js:369:9)

即使我想模拟 doAction,我也可以看到正在调用 doActiononAction 中的 console.logs。 此外,我无法模拟 onAction。我收到这个错误 -

TypeError: Cannot assign to read only property 'onAction' of #<Object>

我试过 jest.fn() 但得到了同样的错误。

我如何模拟这些函数并测试它们?

编辑:

我能够通过以下方式使用 jest.fn() 来模拟 doAction -

let mockFn = jest.fn();
Example.doAction = mockFn()

但是,我仍然无法模拟 Example.props.onAction

最佳答案

在你渲染文档的测试中,你需要传递一个模拟函数,你可以稍后观察它是否被调用,就像这样 -

let onActionMock = jest.fn();

beforeAll(function() {
  Example = TestUtils.renderIntoDocument(<ExampleComponent onAction={onActionMock}/>);
});

beforeEach(function() {
  onActionMock.mockClear();
});

it('doAction calls onAction', () => {
  Example.doAction();
  expect(onActionMock).toBeCalled();
});

您可以进一步测试该函数的调用方式 -

expect(onActionMock).toBeCalledWith('Some argument');

希望这对您有所帮助。

关于javascript - 当在 react 组件中作为 Prop 传递时,如何模拟函数并测试它们是否被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39322966/

相关文章:

javascript - 使用 RGB 格式在 WebGL 中创建纹理时出错

c# - 使用提取和覆盖模式的 TDD 构造函数中的虚拟方法

javascript - 在初始 ReactDOM.render 之后,当 componentDidMount 方法开始触发时,整个 DOM 是否准备就绪?

javascript - 从另一个文件(Cypress、JS)访问变量会导致重复测试运行

javascript - 无法修改已提交 FireStore 的 WriteBatch

xcode - 在 Xcode 单元测试中使用 @testable 时为 "No such module"

java - 在 JVM 上使用 Android XmlPullParser 进行单元测试

javascript - 如何在 React 中添加图标 Fontawesome?

reactjs - 根据 bool 值动态改变图像源

javascript - Node.js 和 MongoDB 中的并发请求处理