В настройке вашей формы есть ошибки. В основном, вы захотите поставить handleSubmit
на onSubmit
опору и изменить одну из кнопок на type
опору submit
. Пожалуйста, смотрите коды и окно для рабочей версии:
Рабочий пример (вы можете запустить тесты, нажав на вкладку Tests
рядом с вкладкой Browser
):
В этом примере используется некоторый синтаксис 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")
);