Unit testing 为什么可以';我是否在jest.mock中模拟函数(必须在spyOn上使用.mock实现)?

Unit testing 为什么可以';我是否在jest.mock中模拟函数(必须在spyOn上使用.mock实现)?,unit-testing,jestjs,enzyme,Unit Testing,Jestjs,Enzyme,我希望当我使用jest.mock()模拟一个模块并将函数实现传递给每个对象时,它们会继续进行测试 import * as services from '_services'; // I thought this would be enough to mock 'load_basket' jest.mock('_services', () => ({ load_basket: jest.fn(() => Promise.resolve([])) })); describe('W

我希望当我使用
jest.mock()
模拟一个模块并将函数实现传递给每个对象时,它们会继续进行测试

import * as services from '_services';

// I thought this would be enough to mock 'load_basket'
jest.mock('_services', () => ({
  load_basket: jest.fn(() => Promise.resolve([]))
}));

describe('WB Component', () => {
  it('loads basket if basket prop is null', () => {

    // However, if I don't use .mockImplemenation here it gives
    // me an error that load_basket wasn't called
    const spy = spyOn(services, 'load_basket').mockImplementation(() => Promise.resolve([]));
    const wrapper = shallow(<WB basket={null} />);
    expect(spy).toHaveBeenCalled();
    wrapper.unmount();
    spy.mockRestore();
  });
});
接受可选的
工厂
参数,如果提供了一个参数,则
模块
将替换为调用
工厂
参数的结果

因此,在调用测试函数时,
services.load\u basket
已经是一个很好的例子


错误详细信息

您正在呼叫
spyOn
,而spyOn最终会呼叫(
Jest
是基于
Jasmine
),我猜您是想呼叫的

Jasmine
中的
spyOn
函数不能与
Jest
mock函数一起正常工作,如果不模拟实现,就会导致出现错误

请注意,如果您调用了
jest.spyOn
,它可能只是因为
load\u basket
已经是一个模拟函数,如果没有模拟实现,它就可以工作


综上所述,您不需要监视
服务。load_basket
,因为它已经是一个模拟函数了

您的测试可以简化为:

import*作为来自“u服务”的服务;
开玩笑。模仿(“U服务”),()=>({
加载篮:jest.fn(()=>Promise.resolve([]))
}));
描述('WB组件',()=>{
它('如果篮道具为空,则加载篮',()=>{
常量包装器=浅();
expect(services.load_basket).toHaveBeenCalled();//成功!
});
});

您能展示一下
load\u basket
是如何在您的
WB
组件中使用的吗?(我猜它被称为对已解决的
承诺的响应,但我只是想确定一下)@brian lives outdoors补充道。哇,调用未记录的遗留代码似乎真的是一种破坏行为。我猜他们不希望人们被它绊倒,但是是的,它可能会发出warning@NilsGuillermin如果您需要帮助来验证
组件安装
中的
承诺
回调中是否正确设置了
状态
,请打开一个新问题并标记我,这样做有点棘手
class WB extends Component {
  constructor(props) {
    super(props);
    this.state = {
      basket: props.basket,
      loading_basket: !props.basket,
    };
  }

  componentDidMount(): void {
    if (!this.state.basket) {
      load_basket()
        .then(res => {
          this.setState({
            basket: res,
            loading_basket: false
          });
        })
        .catch( ... );
    }
  }

  render () { ... }
}