Enzyme/Jest Class 方法间谍未在输入更改时被调用

Enzyme/Jest Class method spy not being called on input change

起初,我以为我的代码的其他方面有问题。所以我在新创建的项目中创建了一个新的简化版本的组件并为其编写了测试,但我的间谍仍然没有被调用。

这是我正在测试的组件:

import React from 'react';

class TextEditor extends React.Component {
  handleChange = (e) => {
    console.log({ value: e.target.value });
  }

  render() {
    return (
      <div>
        <input type="text" name="name" id="name" onChange={this.handleChange} />
      </div>
    );
  }
}

export default TextEditor;

这是单元测试:

import React from 'react';
import { shallow } from 'enzyme';
import TextEditor from '../TextEditor';

describe('TextEditor', () => {
  it('handles change event', () => {
    const wrapper = shallow(<TextEditor />);
    const spy = jest.spyOn(wrapper.instance(), 'handleChange');
    wrapper.find('input').simulate('change', { target: { value: 'test value' }});
    expect(spy).toHaveBeenCalledTimes(1);
  });
});

运行测试结果:

当我 运行 这样做时,它失败了,因为间谍没有被调用。但是请注意 handleChange 函数中的 console.log 语句被执行了。所以测试实际上调用了函数,但间谍未被识别为已被调用。

我做错了什么?谢谢你的想法。

handleChange方法是class属性,不是class的实例方法。

如果你坚持使用class属性,你应该在窥探后调用wrapper.instance().forceUpdate()。参见 issue#365

例如

TextEditor.tsx:

import React from 'react';

class TextEditor extends React.Component {
  handleChange = (e) => {
    console.log({ value: e.target.value });
  };

  render() {
    return (
      <div>
        <input type="text" name="name" id="name" onChange={this.handleChange} />
      </div>
    );
  }
}

export default TextEditor;

TextEditor.test.tsx:

import { shallow } from 'enzyme';
import React from 'react';
import TextEditor from './TextEditor';

describe('TextEditor', () => {
  it('handles change event', () => {
    const wrapper = shallow(<TextEditor />);
    const spy = jest.spyOn(wrapper.instance(), 'handleChange');
    wrapper.instance().forceUpdate();
    wrapper.find('input').simulate('change', { target: { value: 'test value' } });
    expect(spy).toHaveBeenCalledTimes(1);
  });
});

测试结果:

 PASS  examples/70652888/TextEditor.test.tsx (13.006 s)
  TextEditor
    ✓ handles change event (100 ms)

  console.log
    { value: 'test value' }

      at TextEditor.handleChange (examples/70652888/TextEditor.tsx:5:13)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        14.708 s

另外,看这个