反应测试中的间谍功能未触发

时间:2019-08-09 19:25:16

标签: reactjs react-testing-library

我有一个受控组件,其形式由两个单选按钮和一个文本输入组成。我有一个用于文本输入的onChange事件的函数,并编写了一个触发change事件的测试。我希望间谍函数应该被调用一次,但是测试总是会失败。

测试

test('Update function is called when text entered into searchbox', () => {
    const spy = jest.fn();
    const {getByTestId} = render(<SearchDropdown handleChange={spy}/>);
    expect(getByTestId('searchText').value).toBe("");
    fireEvent.change(getByTestId('searchText'), { target: { value: "23" } });
    expect(getByTestId('searchText').value).toBe("23");
    expect(spy).toHaveBeenCalledTimes(1);
});

组件-不带任何道具

import React, { Component } from 'react'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import SearchResults from './SearchResults';

export default class SearchDropdown extends Component {

    constructor(props){
        super(props)

        this.state = {
            type: 'Spec',
            number: '',
        }

    }

    handleChange = (event) => {
        let name = event.target.name;
        let target = event.target.value;
        this.setState({
            [name]: target}
        );
    }

    handleSearch = (event) => {
        event.preventDefault();
        if (this.state.number !== "") {
            console.log("Make request to API");
        }
    }

    render() {
        return (
            <div data-testid="searchMenu">
                <div className="list-group dropdown-menu dropdown-menu-right mr-5 text-center">
                    <h5><FontAwesomeIcon icon={faSearch}/> Quick Search</h5>
                    <form className="m-2">
                        <div className="form-group" onChange={this.handleChange}>
                            <input type="radio" value="Spec" name="type" defaultChecked /> Specification 
                            <input type="radio" value="Claim" name="type" className="ml-2"/> Claim
                        </div>
                        <div className="form-group">
                            <label>Search Number</label>
                            <input type="text" data-testid="searchText" onChange={this.handleChange} value={this.state.number} name="number" className="form-control"/>
                        </div>
                        <SearchResults />
                    </form>
                    <div className="panel panel-default">
                    </div>
                    <button className="bg-transparent border-0 link">Advanced Search</button>
                </div>
            </div>
        )
    }
}

错误消息

expect(jest.fn()).toHaveBeenCalledTimes(1)

    Expected mock function to have been called one time, but it was called zero times.

          fireEvent.change(getByTestId('searchText'), { target: { value: "23" } });
          expect(getByTestId('searchText').value).toBe("23");
          expect(spy).toHaveBeenCalledTimes(1);
                     ^
      });

      test('Clicking search brings up results modal', () => {

      at Object.toHaveBeenCalledTimes (src/Tests/SearchDropdown.test.js:18:17)

我缺少明显的东西吗?

1 个答案:

答案 0 :(得分:0)

我是React和React Testing库的新手,但是我注意到了几件事:

  1. 在您的测试中,您正在将间谍作为道具handleChange的值传递给您的组件,该组件没有该组件;正如您所说的:“ 不带任何道具”。
  2. 您的组件定义 handleChange函数,您可以使用事件处理程序,但不能从道具中获取它。
  3. 您的handleChange函数应仅作为prop传递给输入元素,而不是div。
  4. 每个输入应该有一个处理程序,而不是对所有输入都调用相同的处理程序。

也就是说,为了使测试能够提供任何值,您应该更改您的 SearchDropdown 组件,以便它接收来自父级的处理程序,或者您测试触发输入上的click / change事件实际上会按预期更新视图。 我认为测试内部事件处理程序函数是否具有任何价值。 您在测试中使用的是React Testing Library,但并非按预期的方式使用。 来自React Testing Library Intro

  

该库提供的实用程序可方便地查询   用户将使用相同的方式。通过标签文本查找元素   (就像用户一样),从他们的文本中找到链接和按钮   (就像用户一样)。它还提供了一种建议的查找方法   数据-testid元素作为元素的“逃生舱口”   文字内容和标签没有意​​义或不实际。