Проверьте кнопку дочернего компонента в родительском компоненте - PullRequest
1 голос
/ 02 декабря 2019

Я новичок в тестах и ​​ищу 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: >= 1 Received number of calls: 0 Я тоже готов попробовать по реакции, начинаю, поэтому любая помощь будет приятной.

Заранее спасибо!

1 Ответ

0 голосов
/ 02 декабря 2019

В настройке вашей формы есть ошибки. В основном, вы захотите поставить handleSubmit на onSubmit опору и изменить одну из кнопок на type опору submit. Пожалуйста, смотрите коды и окно для рабочей версии:

Рабочий пример (вы можете запустить тесты, нажав на вкладку Tests рядом с вкладкой Browser):

Edit Simple Form Testing

В этом примере используется некоторый синтаксис es6 , поэтому, если вы не знакомы, прочитайте следующее:


компоненты / 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;

компоненты / Подписаться / Subscribee.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;

компоненты / подписка / __ tests __ / Subscribe.test.js (я передаю onSubmit реквизит, чтобы высмеять его, и я ожидаю, что он будет вызван. Это более распространенный тестовый примерпо сравнению с тестированием против реализации обратного вызова событий React, которая вынуждает вас излишне шпионить за полем класса. Тестируя против prop (или изменения состояния или некоторого вторичного ac), мы уже рассмотрим, работает ли обратный вызов!)

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")
);
...