имитация события щелчка и тестовой функции, вызывающей нажатие истории (jest-enzyme)

#reactjs #jestjs #enzyme

#reactjs #jestjs #enzyme

Вопрос:

Я пытаюсь протестировать компонент с помощью кнопки, которая запускает функцию, функция принимает состояние из useState и переходит к новому маршруту с параметром внутри. Как я могу протестировать функцию? Я получил ошибку :

 TypeError: history.push is not a function
  

Компонент:

 import React, { useState, useEffect } from "react";
import "./Join.css";
import { useHistory } from "react-router-dom";

const Join = () => {
  const history = new useHistory();
  const [joinFormField, setJoinFormField] = useState({
    username: "",
    room: "JavaScript",
  });

  const changeFormHandler = (e) => {
    setJoinFormField({
      ...joinFormField,
      [e.target.name]: e.target.value,
    });
  };

  const joinChatHandler = () => {
    history.push("/chat", {
    user: joinFormField,
  });
  };

  return (
    <div className="JoinContainer">
      <header className="JoinHeader">
        <h1>
          <i className="fas fa-comments"></i> DeveloperChat
        </h1>
      </header>
      <main className="JoinMain">
        <form className="Form">
          <div className="FormControl">
            <label className="Label">NickName</label>
            <input
              className="Input"
              type="text"
              name="username"
              id="username"
              placeholder="Enter nickname..."
              required
              value={joinFormField.userName}
              onChange={changeFormHandler}
            />
          </div>
          <div className="FormControl">
            <label className="Label">Choose Room</label>
            <select
              className="RoomSelect"
              name="room"
              id="room"
              value={joinFormField.room}
              onChange={changeFormHandler}
            >
              <option value="JavaScript">JavaScript</option>
              <option value="Python">Python</option>
              <option value="PHP">PHP</option>
              <option value="C#">C#</option>
              <option value="Ruby">Ruby</option>
              <option value="Java">Java</option>
            </select>
          </div>
          <button className="JoinBtn" onClick={joinChatHandler}>
            Join Chat
          </button>
        </form>
      </main>
    </div>
  );
};

export default Join;
  

файл спецификации:

 import * as React from "react";
import { shallow } from "enzyme";
import Join from "../../../containers/Join/Join";

describe("MyComponent", () => {
  it("should navigate to chat when click on join btn", () => {
    const joinChatHandler = jest.fn();
    const wrapper = shallow(<Join onClick={joinChatHandler} />);
    wrapper.find("button").simulate("click");
    expect(joinChatHandler).toHaveBeenCalled();
  });
});
  

Как я могу протестировать эту функциональность?
Я пытаюсь имитировать объект истории и получаю ту же ошибку.
Спасибо.

Комментарии:

1. Не используйте new ключевое слово с useHistory хуком — это не конструктор.

2. Проблема не в этом, функциональность работает, но тест не выполняется @backtick

3. Я не имел в виду это как ответ, но это все равно неверно.

Ответ №1:

Найдено решение:

 const mockHistoryPush = jest.fn();
jest.mock("react-router-dom", () => ({
  ...jest.requireActual("react-router-dom"),
  useHistory: () => ({
    push: mockHistoryPush,
  }),
}));

describe("click handler", () => {
  it("should navigate to chat when click on join btn", () => {
    const joinFormField = {
      username: "",
      room: "JavaScript",
    };
    wrapper.find("button").simulate("click");

    expect(mockHistoryPush).toHaveBeenCalledWith("/chat", {
      user: joinFormField,
    });
  });
});

 
  

Ответ №2:

Попробуйте использовать :

 this.props.history.push(""/chat")
  

Комментарии:

1. Проблема не в этом, функциональность работает, но тест завершается неудачей