如何用笑话和酶模拟 React 组件方法

IT技术 javascript reactjs jestjs enzyme
2021-04-19 08:29:59

我有一个react组件(这是为了演示问题而简化的):

class MyComponent extends Component {
    handleNameInput = (value) => {
        this.searchDish(value);
    };

    searchDish = (value) => {
      //Do something
    }

    render() {
        return(<div></div>)
    }
}

现在我想用提供的值测试该handleNameInput()调用searchDish

为了做到这一点,我想创建一个替代组件方法笑话模拟函数

到目前为止,这是我的测试用例:

it('handleNameInput', () => {
   let wrapper = shallow(<MyComponent/>);
   wrapper.searchDish = jest.fn();
   wrapper.instance().handleNameInput('BoB');
   expect(wrapper.searchDish).toBeCalledWith('BoB');
})

但我在控制台中得到的只是SyntaxError

语法错误

  at XMLHttpRequest.open (node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:458:15)
  at run_xhr (node_modules/browser-request/index.js:215:7)
  at request (node_modules/browser-request/index.js:179:10)
  at DishAdmin._this.searchDish (src/main/react/components/DishAdmin.js:155:68)
  at DishAdmin._this.handleNameInput (src/main/react/components/DishAdmin.js:94:45)
  at Object.<anonymous> (src/main/react/tests/DishAdmin.test.js:122:24)

所以我的问题是,如何使用酶正确模拟组件方法?

3个回答

可以通过这种方式模拟该方法:

it('handleNameInput', () => {
   let wrapper = shallow(<MyComponent/>);
   wrapper.instance().searchDish = jest.fn();
   wrapper.update();
   wrapper.instance().handleNameInput('BoB');
   expect(wrapper.instance().searchDish).toBeCalledWith('BoB');
})

您还需要在测试组件的包装器上调用 .update 以正确注册模拟函数。

语法错误来自错误的赋值(您需要将方法分配给实例)。我的其他问题来自.update()模拟方法后没有调用

@mojave 如果您componentDidMount通过以下方式手动调用它会起作用wrapper.instance().componentDidMount()
2021-05-22 08:29:59
注意:在 React 16 及更高版本中,instance() 为无状态功能组件返回 null。文档
2021-05-31 08:29:59
对我来说,它抛出并出错expect(wrapper.searchDish)——不是模拟函数或间谍。只有当我改变expect(wrapper.instance().searchDish)它才能正常工作。
2021-06-01 08:29:59
如果wrapper.update();不起作用,您也可以尝试wrapper.instance().forceUpdate();
2021-06-06 08:29:59
@NikSumeiko 即使我遇到了同样的错误,我也将模拟函数存储到一个变量中并进行了检查toBeCalledWithconst searchDishMock = jest.fn(); ... expect(searchDishMock).toBeCalledWith('BoB');
2021-06-16 08:29:59

需要替换wrapper.update();wrapper.instance().forceUpdate();

@Miha 的回答有一个小的变化:

it('handleNameInput', () => {
  let wrapper = shallow(<MyComponent/>);
  const searchDishMock = jest.fn();
  wrapper.instance().searchDish = searchDishMock;
  wrapper.update();
  wrapper.instance().handleNameInput('BoB');
  expect(searchDishMock).toBeCalledWith('BoB');
})
这仍然有效吗?我正在使用 React 16 和酶 3.3.0,但测试没有通过。此外,酶文件似乎没有建议update可以注册模拟功能。
2021-05-30 08:29:59
有谁知道如何使用 React 测试库来做到这一点?
2021-06-03 08:29:59
你不需要它wrapper.update()来让测试通过。
2021-06-13 08:29:59