如何监视在componentDidMount内部调用的方法

时间:2019-05-22 13:54:05

标签: reactjs jestjs

我正在尝试监视在componentDidMount内部调用的方法。该方法本身位于另一个文件中。这是我到目前为止尝试过的:

import apicall from './AnotherFile'
class MyComponent {
    componentDidMount() {
        apicall()
    }
    <other code ->
}

测试:

const wrapper = mount(<MyComponent/>);
const instance = wrapper.instance();
jest.spyOn(instance, 'apicall');
instance.componentDidMount();
expect(instance.apicall).toHaveBeenCalled();

出现错误:

Cannot spy the apicall property because it is not a function; undefined given instead

有什么想法可以实现吗?

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点:

  1. 在测试文件中模拟导入:通过使用jest.mock,Jest将拦截导入并在组件文件中使用时创建模拟版本:

    // MyComponent.test.js
    import apicall from './AnotherFile'
    
    jest.mock('./AnotherFile');
    
    it('makes API call', () => {
      const wrapper = mount(<MyComponent />);
      expect(apicall).toHaveBeenCalled();
    });
    

无需获取instance,无需手动调用componentDidMount,这将在您mount(<MyComponent />)时发生。注意:如果apicall应该返回一个值或一个P​​romise,则可以提供一个模拟值:

// Mock a response if your componentDidMount calls `apicall.then()`...
apicall.mockImplementation(() => Promise.resolve('some value'));
// Mock a rejected Promise to test error cases
apicall.mockImplementation(() => Promise.reject('Oh no!'));
  1. 依赖性注入:将apicall函数传递到您的组件中。您可以将其默认设置为实际导入的apicall,但在测试中可以传递模拟函数:

    // MyComponent.js
    import apicall as realApiCall from './AnotherFile'
    
    class MyComponent extends Component {
    
      static defaultProps = {
        apicall: realApiCall
      }
    
      componentDidMount() {
        // This will call the real apicall if you don't provide
        // a prop: <MyComponent /> ... but allows you to inject
        // a mock apicall function in tests.
        this.props.apicall()
      }
      <other code ->
    }
    
    // MyComponent.test.js
    const apicall = jest.fn();
    const wrapper = mount(<MyComponent apicall={apicall} />);
    expect(apicall).toHaveBeenCalled();
    

答案 1 :(得分:-1)

您模拟了导入的功能。试试这个

    import * as dependency from '../AnotherFile';

    describe('MyComponent', () => {
        it('test apicall', () => {
            dependency.apicall = jest.fn();

            const wrapper = mount(<MyComponent />);
            wrapper.instance().componentDidMount();

            expect(dependency.apicall).toHaveBeenCalled();
        });
    });