【问题标题】:Test a button of a child component in the parent component在父组件中测试子组件的按钮
【发布时间】:2020-03-26 13:48:03
【问题描述】:

我是新的测试和搜索 3 天以来如何解决我的问题。希望你能帮助我.. 我有一个父组件:

import React from 'react';
import './Subscribe.scss';
import Button from '../../Components/Button/Button';

class Subscribe extends React.Component {
    state = {
        user: {
            firstName: '',
            pseudo:'',
            email: '',
            password:''
        }
    }

handleChange = (e) => {
    this.setState({
        user: {...this.state.user, [e.target.name]: e.target.value}
    }, () => console.log(this.state))
}

onSubmit = (e) => {
    //  e.preventDefault()
    console.log("you've clicked")
    //todo
}
    render() {
        return(
            <form className='subscribe' id='subscriptionForm'>
                <label htmlFor='firstName'>Prénom :</label>
                    <input
                        data-testid='inputString'
                        type='text'
                        name='firstName'
                        onChange={this.handleChange}
                        value={this.state.user.firstName}
                    />

                <label htmlFor='pseudo'>Pseudo :</label>
                    <input
                        data-testid='inputString'
                        type='text'
                        name='pseudo'
                        onChange={this.handleChange}
                        value={this.state.user.pseudo}
                    />
                <label htmlFor='email'>Email :</label>
                    <input
                        data-testid='inputString'
                        type='email'
                        name='email'
                        onChange={this.handleChange}
                        value={this.state.user.email}
                    />
                <label htmlFor='password'>
                    password :
                </label>
                <Button id='submitSubscription' text='Go go !' onSubmit={this.onSubmit}/>
                <Button text='Annuler'/>
            </form>
        )
    }
}

export default Subscribe;

子组件:

import React from "react";

const Button = (props) => {
    return (
        <button type="button" onClick={props.onClick}>{props.text}</button>
    )
}
Button.displayName = 'Button'
export default Button

我想测试它,但没有任何效果......

我的测试:


import React from 'react';
import { shallow, mount } from 'enzyme';
import Subscribe from './Subscribe.js';
import Button from "./../../Components/Button/button.js"


describe('<LogIn />', () => {
    it('Should call onSubmit on subscribe component when button component is clicked and allow user to subscribe ', () => {
        // Rend le composant et les enfants et renvoie un wrapper Enzyme
        const wrapper = mount(<Subscribe />);
        // Trouve la première balise bouton
        const button = wrapper.find("#submitSubscription");
        // Récupère l'instance React du composant
        const instance = wrapper.instance();
        // Ecoute les appels à la fonction on Submit
        jest.spyOn(instance, "onSubmit");
        button.simulate('click');
        expect(instance.onSubmit).toHaveBeenCalled();
    })

评论是我尝试过的。 答案还是Expected number of calls: &gt;= 1 Received number of calls: 0 我也愿意通过反应测试来尝试,我开始了,所以任何帮助都是一种乐趣。

提前致谢!

【问题讨论】:

    标签: javascript reactjs jestjs enzyme


    【解决方案1】:

    您的表单设置有一些错误。主要是,您需要在formonSubmit 属性上放置一个handleSubmit,并将其中一个按钮更改为type 属性为submit。请查看代码框以获取工作版本:

    工作示例(您可以通过单击Browser 标签旁边的Tests 标签来运行测试):

    这个例子使用了一些es6 syntax,所以如果你不熟悉,请阅读以下内容:


    components/Button/Button.js

    import React from "react";
    
    const Button = props => (
      <button
        style={{ marginRight: 10 }}
        type={props.type || "button"}
        onClick={props.onClick}
      >
        {props.text}
      </button>
    );
    
    Button.displayName = "Button";
    
    export default Button;
    

    components/Subscribe/Subcribe.js

    import React, { Component } from "react";
    import Button from "../Button/Button";
    // import './Subscribe.scss';
    
    const initialState = {
      user: {
        firstName: "",
        pseudo: "",
        email: "",
        password: ""
      }
    };
    
    class Subscribe extends Component {
      state = initialState;
    
      handleChange = ({ target: { name, value } }) => {
        // when spreading out previous state, use a callback function
        // as the first parameter to setState
        // this ensures state is in sync since setState is an asynchronous function
        this.setState(
          prevState => ({
            ...prevState,
            user: { ...prevState.user, [name]: value }
          }),
          () => console.log(this.state)
        );
      };
    
      handleCancel = () => {
        this.setState(initialState);
      };
    
      handleSubmit = e => {
        e.preventDefault();
        this.props.onSubmit(this.state);
      };
    
      render = () => (
        <form
          onSubmit={this.handleSubmit}
          className="subscribe"
          id="subscriptionForm"
        >
          <label htmlFor="firstName">Prénom :</label>
          <input
            data-testid="inputString"
            type="text"
            name="firstName"
            onChange={this.handleChange}
            value={this.state.user.firstName}
          />
          <br />
          <label htmlFor="pseudo">Pseudo :</label>
          <input
            data-testid="inputString"
            type="text"
            name="pseudo"
            onChange={this.handleChange}
            value={this.state.user.pseudo}
          />
          <br />
          <label htmlFor="email">Email :</label>
          <input
            data-testid="inputString"
            type="email"
            name="email"
            onChange={this.handleChange}
            value={this.state.user.email}
          />
          <br />
          <label htmlFor="password">password :</label>
          <input
            data-testid="inputString"
            type="password"
            name="password"
            onChange={this.handleChange}
            value={this.state.user.password}
          />
          <br />
          <br />
          <Button type="button" text="Annuler" onClick={this.handleCancel} />
          <Button id="submitSubscription" type="submit" text="Soumettre" />
        </form>
      );
    }
    
    export default Subscribe;
    

    components/Subscribe/__tests__/Subscribe.test.js(我传入了一个 onSubmit 属性来模拟它,我希望它会被调用。这是一个更常见的测试用例与针对 React 的事件回调实现进行测试相比,这会迫使您不必要地监视类字段。通过针对 prop(或状态更改或某些辅助操作)进行测试,我们已经涵盖了回调是否有效!)

    import React from "react";
    import { mount } from "enzyme";
    import Subscribe from "../Subscribe.js";
    
    const onSubmit = jest.fn();
    
    const initProps = {
      onSubmit
    };
    
    describe("<LogIn />", () => {
      it("Should call onSubmit on subscribe component when button component is clicked and allow user to subscribe ", () => {
        const wrapper = mount(<Subscribe {...initProps} />);
        const spy = jest.spyOn(wrapper.instance(), "handleSubmit"); // not necessary
        wrapper.instance().forceUpdate(); // not necessary
    
        wrapper.find("button[type='submit']").simulate("submit");
    
        // alternatively, you could simply use:
        // wrapper.find("form").simulate("submit");
    
        expect(spy).toHaveBeenCalledTimes(1); // not necessary
        expect(onSubmit).toHaveBeenCalledTimes(1);
      });
    });
    

    index.js

    import React from "react";
    import { render } from "react-dom";
    import Subscribe from "./components/Subscribe/Subscribe";
    import "./styles.css";
    
    const onSubmit = formProps => alert(JSON.stringify(formProps, null, 4));
    
    render(
      <Subscribe onSubmit={onSubmit} />,
      document.getElementById("root")
    );
    

    【讨论】:

    • 非常感谢您的帮助,我明白了,非常好:)
    猜你喜欢
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 2019-03-07
    • 2022-01-23
    • 2020-03-05
    • 2021-07-13
    相关资源
    最近更新 更多