Тестирование React Hooks в компоненте - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть компонент, который делает запрос данных при монтировании:

import React from "react";
import { get } from "lodash";
import { Button } from "react-bootstrap";
import StatBox from "./StatBox";
import TeamInfo from "./TeamInfo";
import MlbScore from "../mlb/MlbScore";
import NbaScore from "../nba/NbaScore";
import GameStatus from "./GameStatus";
import useMoveGame from "../../hooks/useMoveGame";
import useGameFeed from "../../hooks/useGameFeed";

import "../../styles/ScoreBoard.css";

export default function ScoreBoard(props) {
  const [data, loading, isError] = useGameFeed(props.url);
  const [
    period,
    status,
    marker,
    buttonText,
    incrementMlb,
    incrementNba
  ] = useMoveGame(0, "bot");

  let content;
  let league;

  if (loading) {
    content = <div>Loading...</div>;
  } else if (isError) {
    content = <div>Error</div>;
  } else if (get(data, "league") === "NBA") {
    league = "NBA";
    content = <NbaScore {...data} />;
  } else if (get(data, "league") === "MLB") {
    league = "MLB";
    content = <MlbScore data={data} period={period} marker={marker} />;
  }

  const handleClick = e => {
    e.preventDefault();
    if (league === "MLB") {
      incrementMlb(marker, period);
    } else if (league === "NBA") {
      incrementNba(marker, period);
    }
  };

  const { start_date_time } = get(data, "eventInfo", "");

  return (
    <div id="scoreboard">
      <div id="team-info-container">
        <TeamInfo team={get(data, "away_team")} status="away" />
        <GameStatus
          status={status}
          startDateTime={start_date_time}
          period={period}
          marker={marker}
        />
        <TeamInfo team={get(data, "home_team")} status="home" />
      </div>
      {content}
      <StatBox
        type={league}
        away={get(data, "stats.away")}
        home={get(data, "stats.home")}
      />
      <div className="start-button-container">
        <Button variant="success" onClick={e => handleClick(e)}>
          {buttonText}
        </Button>
      </div>
    </div>
  );
}

Я пытаюсь проверить, что компонент получает правильные данные от "useGameFeed":

import { useState, useEffect } from 'react';

const useGameFeed = (feedUrl) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [isError, setIsError] = useState(false);
  
  useEffect(() => {
    const getGameData = async () => {
      setIsError(false);
      setLoading(true);
      try {
        console.log(feedUrl);
        const response = await fetch(feedUrl);
        const gameData = await response.json();
        setData(gameData);
      } catch (err) {
        setIsError(true);
      }
      setLoading(false);
    }
    getGameData();
  }, [feedUrl])

  return [data, loading, isError];
};

export default useGameFeed;

Я дошел до этого далеко, но до сих пор не могу понять, как смоделировать ловушку и правильно ли отобразить полученные компоненты в компоненте:

import React from "react";
import { act } from 'react-dom/test-utils';
import { shallow } from "enzyme";
import ScoreBoard from "../../scoreboard/ScoreBoard";
import useGameFeed from "../../../hooks/useGameFeed";
import { testHook } from "../../../hooks/TestHook";

const mlbData = require("../structures/mlbData.json");
const nbaData = require("../structures/nbaData.json");

describe("ScoreBoard", () => {
  let wrapper;

  describe("MLB ScoreBoard", () => {
    beforeAll(() => {
      jest.spyOn(global, "fetch").mockImplementation(() =>
        Promise.resolve({
          json: () => Promise.resolve(mlbData)
        })
      );
      wrapper = shallow(<ScoreBoard url="https://example.com" />);
    });

    afterEach(() => {
      global.fetch.mockClear();
    });
    afterAll(() => {
      global.fetch.mockRestore();
    });

    it("renders without crashing", () => {
      shallow(<ScoreBoard url="https://example.com" />);
    });

    it("renders the value given", () => {
      wrapper = shallow(<ScoreBoard url="https://example.com" />);
      console.log(wrapper.debug());
    });
  });
});

Что возвращает debug():

      <div id="scoreboard">
        <div id="team-info-container">
          <TeamInfo team={[undefined]} status="away" />
          <GameStatus status="pending" startDateTime={[undefined]} period={0} marker="bot" />
          <TeamInfo team={[undefined]} status="home" />
        </div>
        <StatBox type={[undefined]} away={[undefined]} home={[undefined]} />
        <div className="start-button-container">
          <Button variant="success" onClick={[Function: onClick]} active={false} disabled={false} type="button">
            Start Game
          </Button>
        </div>
      </div>

Я видел несколько шаблонов, которые включают в себя обертывание хука в компоненте, но похоже, что он предназначен для проверки фактического пользовательского хука, а не поведения компонента. Есть ли способ, которым я могу посмеяться над тем, что мой хук делает в компоненте?

Кроме того, я понимаю, что, поскольку это будет обновление состояния, мне нужно будет использовать act(), но я не совсем уверен, гдечто бы пошло.

Любая помощь очень ценится!

...