【问题标题】:How to mock external module method?如何模拟外部模块方法?
【发布时间】:2017-03-29 01:04:17
【问题描述】:

我有这个模块,里面有一个函数:

const utils = {
  redirectTo(url) {
    if (url) {
      window.location = url;
    }
  },
};

export default utils;

它在 React 组件中的某处使用,如下所示:

import utils from '../../lib/utils';

componentWillUpdate() {
  this.redirectTo('foo')
}

现在我想检查调用redirectTo 的值是否等于foo

  it('should redirect if no rights', () => {
    const mockRedirectFn = jest.fn();
    utils.redirectTo = mockRedirectFn;

    mount(
      <SomeComponent />,
    );

    expect(mockRedirectFn).toBeCalled();
    expect(mockRedirectFn).toBeCalledWith('foo');
    console.log(mockRedirectFn.mock);
    // { calls: [], instances: [] }
  });

这就是我所拥有的,但它不起作用。我该怎么做?

【问题讨论】:

  • 组件在哪里调用了函数?
  • componentWillUpdate,也会更新描述

标签: javascript reactjs unit-testing jestjs


【解决方案1】:

你必须像这样模拟lib/utils 模块:

import utils from '../../lib/utils';
jest.mock('../../lib/utils', () => ({
  redirect: jest.fn()
}))

it('should redirect if no rights', () => {
  mount(
    <SomeComponent />,
  );
  expect(utils.redirect).toHaveBeenCalledWith();
});

这会将模块替换为仅返回 {redirect:jest.fn()} 的模拟。这个模块也被导入到你的测试中,然后你可以访问redirect 的间谍并测试它是用正确的参数调用的。

【讨论】:

    【解决方案2】:

    这是我最终使用的:

     it('should redirect if no rights', () => {
    
        // this way we mock only one method: redirectTo
        jest.mock('lib/utils', () => {
          const original = require.requireActual('lib/utils');
          original.default.redirectTo = jest.fn();
          return original;
        });
    
        const redirectTo = require.requireMock('lib/utils').default.redirectTo;
    
        mount(
          <SomeComponent />,
        );
    
        expect(redirectTo).toHaveBeenCalled();
      });
    

    【讨论】:

    • require.requireActual('lib/utils') 正是我想要的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 2018-01-18
    • 2021-04-04
    • 2021-03-12
    • 1970-01-01
    相关资源
    最近更新 更多