在 useEffect 中使用 jest.spyOn 模拟获取

问题描述 投票:0回答:0

我需要在 useEffect 中模拟我的 fetch 函数,我正在努力做到这一点。我的 useEffect 看起来像这样:

useEffect(() => {
    onSelectedCityHandler({
      name: "Odesa",
      state: "Ukraine",
      lat: 46.4843023,
      lon: 30.7322878,
    });
  }, []);

在 useEffect 中,我调用了一个函数,它进行了两个单独的 API 调用:

function onSelectedCityHandler(cityData: SearchedCityType) {
    setShowCitySelection(false);

    fetchCurrentWeatherData(cityData);
    fetchForecatsForFiveDays(cityData);

    setSearchedCitySelection([
      {
        name: "",
        state: "",
        lat: 0,
        lon: 0,
      },
    ]);
    reset({
      city: "",
    });
    clearErrors("city");
    onFocusHandler();
  }
  
  function fetchCurrentWeatherData(cityData: SearchedCityType) {
    fetch(
      `https://api.openweathermap.org/data/2.5/weather?lat=${cityData?.lat}&lon=${cityData?.lon}&units=metric&appid=${process.env.REACT_APP_API_KEY}`
    )
      .then((response) => response.json())
      .then((response) => {
        onWeatherChange({
          date: transformDate(new Date()),
          city: cityData?.name.split(",")[0],
          temp: Math.round(response.main.temp),
          weatherDescription: response.weather[0].main,
          humidity: response.main.humidity,
          windSpeed: Math.round(response.wind.speed),
        });
      })
      .catch(() => {
        setShowPopup(true);
      });
  }

  function fetchForecatsForFiveDays(cityData: SearchedCityType) {
    fetch(
      `https://api.openweathermap.org/data/2.5/forecast?lat=${cityData?.lat}&lon=${cityData?.lon}&units=metric&appid=${process.env.REACT_APP_API_KEY}`
    )
      .then((response) => response.json())
      .then((response) => {
        console.log(response);
        const forecastId: number = response.city.id;

        const fiveDayForecast: CurrentWeatherType[] = response.list.map(
          (data: WeatherForecast, i: number) => {
            return {
              id: forecastId + i,
              date: data.dt,
              city: cityData?.name.split(",")[0],
              temp: Math.round(data.main.temp),
              weatherDescription: data.weather[0].main,
              humidity: data.main.humidity,
              windSpeed: Math.round(data.wind.speed),
            };
          }
        );
        onWeatherForecast(fiveDayForecast);
      })
      .catch(() => {
        setShowPopup(true);
      });
  }

我的测试代码是这样的。但是我收到的错误是 Argument of type '{ country: string;纬度:数字;本地名称:{ ar:字符串;是:字符串; CA:字符串; }; lon:数字;名称:字符串;状态:字符串; }' 不可分配给类型为'Response |承诺'。 对象字面量只能指定已知属性,并且“国家”不存在于类型“Response |承诺'

describe("mock fetch", () => {
  test("test", async () => {
    render(<App />);
    const user = userEvent.setup();
    const input: HTMLInputElement = screen.getByRole("combobox", {
      name: /city/i,
    });
    user.type(input, "Lviv");
    mockedFetch.mockResolvedValue({
      country: "UA",
      lat: 49.841952,
      local_names: { ar: "لفيف", be: "Львоў", ca: "Lviv" },
      lon: 24.0315921,
      name: "Lviv",
      state: "Lviv Oblast",
    });
  });
});

显然我在 mockResolvedValue 方法中做错了。但是什么?

mocking fetch ts-jest
© www.soinside.com 2019 - 2024. All rights reserved.