Jest 嘲笑间谍功能,未在测试中调用

Jest mocked spy function, not being called in test

组件:

带有 onChange 处理程序的输入组件:

<Field
    component={FormattedTextInput}
    className={colMd113}
    name={NAMES.VEHICLE_YEAR}
    label={constants.VEHICLE_YEAR}
    validate={[required, validator.validateYearOfVehicle]}
    formatting="9999"
    onChange={this.yearOnChange}
/>

方法:

constructor(props) {
    super(props);

    this.yearOnChange = this.yearOnChange.bind(this)
}

yearOnChange(event) {
    if (event.target && event.target.value) {
        const value = event.target.value;
        this.setState({
            year: value
        });
    }
}

测试

it('yearOnChange method is called', function() {
    const spy = jest.spyOn(wrapper.instance(), 'yearOnChange');
    wrapper.update();
    // const instance = wrapper.instance();
    // console.log('instance', instance);
    wrapper.simulate('change', {
        target: {
            name: 'vehicleYear',
            value: '1999'
        }
    });
    expect(spy).toHaveBeenCalled();
});

错误

Vehicle Picker Component › yearOnChange method is called

   expect(jest.fn()).toBeCalled()

   Expected mock function to have been called, but it was not called.

     50 |         console.log(wrapper.instance())
     51 |
   > 52 |         expect(spy).toBeCalled();
        |                     ^
     53 |     });

这是我在登录 wrapper.instance()

时看到的内容
VehiclePicker {
       props: {},
       context: {},
       refs: {},
       updater:
        Updater {
          _renderer:
           ReactShallowRenderer {
             _context: {},
             _element: [Object],
             _instance: [Circular],
             _newState: null,
             _rendered: [Object],
             _rendering: false,
             _forcedUpdate: false,
             _updater: [Circular],
             _dispatcher: [Object],
             _workInProgressHook: null,
             _firstWorkInProgressHook: null,
             _isReRender: false,
             _didScheduleRenderPhaseUpdate: false,
             _renderPhaseUpdates: null,
             _numberOfReRenders: 0 },
          _callbacks: [] },
       state:
        { year: '',
          make: '',
          makeArray: [],
          model: '',
          modelArray: [],
          token: '' },
       yearOnChange: [Function: bound yearOnChange],
       makeOnChange: [Function: bound makeOnChange],
       setState: [Function] }

更新

使用以下代码,expect(result).toEqual('1999') 测试有效!但是 expect(spy).toHaveBeenCalled() 仍然没有 :( 当我实例化方法 yearOnChange 并实际更改组件中的状态时,为什么仍然没有检测到间谍已被调用?

it('yearOnChange method is called', function() {
   const spy = jest.spyOn(VehiclePicker.prototype, 'yearOnChange');
   wrapper.instance().forceUpdate();

   const event = {
       target: {
           value: '1999'
       }
   };

   wrapper.instance().yearOnChange(event);
   wrapper.simulate('change', event);

   const result = wrapper.state('year');
   console.log('result', result); // result = 1999
   expect(result).toEqual('1999');
   expect(spy).toHaveBeenCalled();
});

您正在监视并手动调用 yearOnChange。

尽量不要调用 wrapper.instance().yearOnChange(event);

调用wrapper.instance().onChange事件,或者像你一样,运行模拟('change')就足够了。

你也可以试试VehiclePicker.prototype.yearOnChange = jest.fn()

expect(VehiclePicker.prototype.yearOnChange).toBeCalled();

从这里的答案中找到了很大的帮助:

这是我遗漏的重要步骤:

const instance = wrapper.instance()
const spy = jest.spyOn(instance, 'yearOnChange')

已更新工作测试,有 2 个工作 expects

it('yearOnChange method is called', function() {
    const instance = wrapper.instance();  // <-- Needed to do this here
    const spy = jest.spyOn(instance, 'yearOnChange');  // <-- Then use instance here
    wrapper.instance().forceUpdate();
    
    const event = {
        target: {
            value: '1999'
        }
    };

    wrapper.instance().yearOnChange(event);
    wrapper.simulate('change', event);

    const result = wrapper.state('year');
    console.log('result', result); // result = 1999
    expect(result).toEqual('1999');
    expect(spy).toHaveBeenCalled();
});