使用 react 和 jest 测试文本输入

Jak*_*nge 6 ecmascript-6 reactjs jestjs react-bootstrap

我在我的一个小型测试项目中有一个简单的SearchBar组件。这个 SearchBar 主要由一个文本输入和一个按钮组成,按钮点击执行一个来自输入字段的文本的回调。

我的Searchbar.render方法如下所示:

  return (
    <FormGroup controlId="keywords">
      <InputGroup>
        <FormControl type="text"
                     placeholder="Keywords…"
                     value={this.state.keywords}
                     onChange={this.updateKeywords} />
        <InputGroup.Button
          onClick={() => {this.props.onSearch(this.state.keywords);}}
          ref="searchInput">
          <Button ref="searchButton">
            <Glyphicon glyph="search"/>
          </Button>
        </InputGroup.Button>
      </InputGroup>
    </FormGroup>
  );
Run Code Online (Sandbox Code Playgroud)

我已经使用 jest 为它编写了一个测试

it("should adjust keywords and trigger onSearch correctly", () => {
  const handleSearch = jest.fn();

  const searchBar = ReactTestUtils.renderIntoDocument(
    <Searchbar onSearch={handleSearch}/>
  );
  expect(searchBar.state.keywords).toBe("");

  const button = ReactDOM.findDOMNode(searchBar.refs.searchButton);
  const input = ReactDOM.findDOMNode(searchBar.refs.searchInput);

  ReactTestUtils.Simulate.change(input, {target: {value: "test"}});

  ReactTestUtils.Simulate.click(button);
  expect(handleSearch).toHaveBeenCalledWith("test");
});
Run Code Online (Sandbox Code Playgroud)

现在此测试中的回调工作正常,并且存储在callMeget 中的函数按预期调用。这SearchBar也适用于我的应用程序,所以我认为SearchBar代码是正确的。但是当我npm test用来运行我的测试时,测试失败了:

expect(jest.fn()).toHaveBeenCalledWith(expected)

Expected mock function to have been called with:
  ["test"]
But it was called with:
  [""]
Run Code Online (Sandbox Code Playgroud)

在评论中Andreas Köberle向我指出了该updateKeywords方法似乎没有被调用的问题,这应该是测试失败的原因。遗憾的是,我无法弄清楚为什么在测试中没有调用此方法。

And*_*rle 2

您必须自己传递事件数据,因为它不会真正触发 DOM 元素上的事件。来自文档:

您必须提供您在组件中使用的任何事件属性(例如 keyCode 等),因为 React 不会为您创建任何这些属性。

通常将间谍函数作为回调放入组件中,并在模拟事件后对其进行测试。

const handleSearch = jest.fn();
const searchBar = ReactTestUtils.renderIntoDocument(
    <Searchbar onSearch={handleSearch}/>
);
ReactTestUtils.Simulate.change(input, {target: {value: 'test'}});
expect(handleSearch).toHaveBeenCalledWith('test')
Run Code Online (Sandbox Code Playgroud)