Как я могу издеваться над возвращением данных из пользовательского хука в React / Jest? - PullRequest
2 голосов
/ 01 мая 2020

У меня есть пользовательский хук, называемый useFetch, который просто извлекает данные и возвращает их, в моем тесте компонентов я хочу просто смоделировать этот хук, чтобы вернуть некоторые фальшивые данные, как я могу go сделать это?

import React, { useEffect, useState } from 'react';

export const useFetch = (url: string) => {
  const [data, setData] = useState();

  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url);
        const json = await res.json();
        setData(json);
      } catch (error) {
        console.log(error);
      }
    };

    fetchData();
  }, [url]);

  return data;
};

const App = () => {
  const config = useFetch(`/api/url`);

  return (
    <div></div>
  );
};

export default App;

Могу ли я в любом случае смоделировать useFetch, чтобы в моем тесте Jest для const config были установлены фиктивные данные?

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Я предложу поместить ваш хук в отдельный файл, скажем, useFetch.js содержит

import { useEffect, useState } from "react";

export const useFetch = (url: string) => {
  const [data, setData] = useState();

  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url);
        const json = await res.json();
        setData(json);
      } catch (error) {
        console.log(error);
      }
    };

    fetchData();
  }, [url]);

  return data;
};

Сохраняя файл компонента приложения следующим образом

import React from "react";

import { useFetch } from "./useFetch";


const App = () => {
  const config = useFetch(`/api/url`);

  return (
    <div></div>
  );
};

export default App;

с указанным выше разделением, вы можете легко смоделируйте ваш хук, пример тестового файла следующим образом

import React from "react";
import { render } from "@testing-library/react";
import App from "./App";


// mock config
const mockConfig = {
    data: "mock data"
};

// this will mock complete file, we have provided mock implementation
// for useFetch function
jest.mock("./useFetch", () => ({
    useFetch: () => mockConfig
}));

test("should render with mock useFetch", () => {
    const { getByText } = render(<App />);
    // test logic goes here
});


Предполагая, что все файлы находятся в одном каталоге.

0 голосов
/ 01 мая 2020

ИМХО, вы не должны издеваться над хуком, потому что код внутри него не будет покрыт вашим тестом.

Простым решением будет реализация фиктивной функции, которая переопределит функцию fetch вернуть поддельные данные:

function mockFetch(data) {
  return jest.fn().mockImplementation(() =>
    Promise.resolve({
      ok: true,
      json: () => data
    })
  );
}

it('fetchData()', async () => {
  const mockData = { foo: "bar" };

  window.fetch = mockFetch(mockData);

  const data = await fetchData(`/api/url`);

  // validate returned data
  expect(data).toEqual(mockData);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...