如何在反应组件的孩子中模拟e.preventDefault

时间:2017-01-24 13:20:48

标签: unit-testing reactjs mocha sinon enzyme

我真的不知道如何在反应组件的孩子中模拟内联函数

我的筹码:sinonchaienzyme;

组件用法:

<ListItem onClick={() => someFn()} />

组件的渲染:

render() {
    return (
      <li>
        <a href="#" onClick={e => {
            e.preventDefault();
            this.props.onClick();
          }}
        > whatever </a>
      </li>
    );
  }

我们onClick调用了e.preventDefault()。如何告诉<a href>link)不要拨打e.preventDefault()?我该如何模仿onClick

低于我在测试中尝试的内容:

浅拷贝设置

function setup() {
  const someFn = sinon.stub();

  const component = shallow(
    <ListItem
      onClick={() => {
        someFn();
      }}
    />
  );

  return {
    component: component,
    actions: someFn,
    link: component.find('a'),
    listItem: component.find('li'),
  }
}

和测试

  it('simulates click events', () => {
    const { link, actions } = setup();
    link.simulate('click'); //Click on <a href>
    expect(actions).to.have.property('callCount', 1); //would be good if we'll remove e.preventDefault()
  });

测试输出错误:

TypeError: Cannot read property 'preventDefault' of undefined

7 个答案:

答案 0 :(得分:61)

试试这个

link.simulate('click', {
  preventDefault: () => {
  }
 });

答案 1 :(得分:3)

 test('simulates click events', () => {
    const e = { stopPropagation: jest.fn() };
    const component = shallow(<ListItem{...props} />);
    const li = component.find('li').at(0).childAt(0)
    li.props().onClick(e)

    expect();
  });

答案 2 :(得分:3)

仅需注意,这仅在使用is ArrayList酶呈递剂时才存在。如果使用完整的DOM渲染器shallow,则事件对象包含mount方法,因此您不必模拟它。

答案 3 :(得分:2)

对于那些使用Jest和react-testing-library s fireEvent的用户,您需要提供一个初始化的事件对象,否则无法通过您的元素调度该事件。

然后可以通过为该初始化事件分配属性来断言e.preventDefault上的断言:

test('prevents default on click', () => {
  const {getByText} = render(<MyComponent />);
  const button = getByText(/click me/);

  // initialise an event, and assign your own preventDefault
  const clickEvent = new MouseEvent('click');
  Object.assign(clickEvent, {preventDefault: jest.fn()});

  fireEvent(button, clickEvent);

  expect(event.preventDefault).toHaveBeenCalledTimes(1);
});

stopPropagation类似。

Anton Karpenko's answer for Jest很有用。

答案 4 :(得分:2)

您可以通过一些测试工具定义具有您要模拟的功能的对象,例如,查看 Jest

describe('Form component', () => {
  test('deos not reload page after submition', () => {
    const wrapper = shallow(<TodosForm />)
    // an object with some function
    const event = { preventDefault: () => {} }
    // mocks for this function
    jest.spyOn(event, 'preventDefault')
    wrapper.find('form').simulate('submit', event)
    // how would you know that function is called
    expect(event.preventDefault).toBeCalled()
  })
})

答案 5 :(得分:1)

我建议使用

基于jest.fn()创建新对象
const event = Object.assign(jest.fn(), {preventDefault: () => {}})

然后使用它:

element.simulate('click', event);

答案 6 :(得分:1)

我正在使用Web组件,这对我有用-

  const callback = jest.fn();
  MouseEvent.prototype.stopPropagation = callback;
  const element = createElement({});
  element.shadowRoot.querySelector('ul').click();
  expect(callback).toHaveBeenCalledTimes(1);