【问题标题】:Spy function in react test is not firing反应测试中的间谍功能未触发
【发布时间】:2019-12-17 13:09:31
【问题描述】:

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

测试

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)

我是否遗漏了一些明显的东西?

【问题讨论】:

    标签: reactjs react-testing-library


    【解决方案1】:

    我对 React 和 React 测试库还很陌生,但我注意到了一些事情:

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

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

    这个库提供的实用程序有助于在 与用户相同的方式。通过标签文本查找元素 (就像用户一样),从他们的文本中找到链接和按钮 (就像用户一样)。它还公开了一种推荐的查找方式 data-testid 的元素作为元素的“逃生舱”,其中 文字内容和标签没有意​​义或不实用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多