【问题标题】:How to mock functions, and test that they're called, when passed as props in react components?当在反应组件中作为道具传递时,如何模拟函数并测试它们是否被调用?
【发布时间】:2017-01-12 08:58:54
【问题描述】:

我正在关注这个 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)

我可以看到doActiononAction 中的console.logs 被调用,即使我想模拟doAction。 另外,我无法模拟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

【问题讨论】:

    标签: javascript unit-testing reactjs jestjs


    【解决方案1】:

    在渲染文档时的测试中,您需要传递一个模拟函数,您可以稍后查看它是否被调用,类似这样 -

    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');
    

    希望这会有所帮助。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-30
    • 2021-10-01
    • 2021-12-29
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2020-07-16
    相关资源
    最近更新 更多