简体   繁体   English

我应该在这个包装 useSWR 的自定义钩子中测试什么?

[英]What should i test in this custom hook that is wrapping useSWR?

I have created a custom hook called useCity.我创建了一个名为 useCity 的自定义钩子。 It is wrapping an API call made using useSWR.它封装了使用 useSWR 进行的 API 调用。

Here is the code for hook:这是钩子的代码:

import useSWR from 'swr';

import { City } from '../interfaces';
import { BASE_URL } from '../../config';

interface CitiesResponse {
  data?: {
    records: {
      fields: {
        city: string;
        accentcity: string;
      }
    }[]
  },
  error?: {
    message: string;
  }
};

interface Props {
  start?: number;
  rows: number;
  query?: string;
  sort?: 'population';
  exclude?: string[];
}

const useCity = ({ start = 0, rows, query, sort, exclude }: Props) => {
  const params = [`start=${start}`, `rows=${rows}`];
  if (query) params.push(`q=${query}`);
  if (sort) params.push(`sort=${sort}`);
  if (exclude && exclude.length > 0) params.push(...exclude.map(city => `exclude.city=${city}`))

  const { data, error }: CitiesResponse = useSWR(
    `${BASE_URL.CITIES_SERVICE}?dataset=worldcitiespop&facet=city&${params.join('&')}`,
    { revalidateOnFocus: false,  }
  );

  const cities: City[] = data?.records.map(record => ({
    name: record.fields.city,
    title: record.fields.accentcity,
  })) || [];

  return {
    cities,
    loading: !error && !data,
    error,
  };
};

export default useCity;

Now, I need to test the hook.现在,我需要测试钩子。 So, I tried using msw and @testing-library/react-hooks .所以,我尝试使用msw@testing-library/react-hooks

Here is my try:这是我的尝试:

const server = setupServer(
  rest.get(BASE_URL.CITIES_SERVICE, (req, res, ctx) => {
    const start = req.url.searchParams.get('start');
    const rows = req.url.searchParams.get('rows');
    const query = req.url.searchParams.get('query');
    const sort = req.url.searchParams.get('sort');
    const exclude = req.url.searchParams.getAll('exclude.city');

    const getReturnVal: () => DatabaseCity[] = () => {
      // i will write some code that assumes what server will return
    };


    return res(
      ctx.status(200),
      ctx.json({
        records: getReturnVal(),
      }),
    );
  }),
  ...fallbackHandlers,
);

beforeAll(() => server.listen());
afterEach(() => {
  server.resetHandlers();
  cache.clear();
});
afterAll(() => server.close());


it('should return number of cities equal to passed in rows', async () => {
  const wrapper = ({ children } : { children: ReactNode }) => (
    <SWRConfig value={{ dedupingInterval: 0 }}>
      {children}
    </SWRConfig>
  );

  const { result, waitForNextUpdate, } = renderHook(() => useCity({ rows: 2 }), { wrapper });
  const { cities:_cities, loading:_loading, error:_error } = result.current;
  expect(_cities).toHaveLength(0);
  
  await waitForNextUpdate();
  
  const { cities, loading, error } = result.current;
  expect(cities).toHaveLength(2);
});

I assme that the test case will pass once I implement the mock function.我认为一旦我实现了模拟功能,测试用例就会通过。

But I don't know if this is the right approach to test such a hook.但我不知道这是否是测试这种钩子的正确方法。 I am a frontend developer, is this my responsibility to test that API call?我是一名前端开发人员,这是我测试 API 调用的责任吗?

I am new to writing test cases that involves API calls.我是编写涉及 API 调用的测试用例的新手。 Am I going in the right direction?我是否朝着正确的方向前进? I don't know what this kind of tests are called.我不知道这种测试叫什么。 If someone can tell me the kind of the test I am perfoming, then it will help me google for the solutions instead of wasting other developer's time to answer my questions.如果有人能告诉我我正在执行的测试类型,那么它将帮助我 google 寻找解决方案,而不是浪费其他开发人员的时间来回答我的问题。

Looks like you are on the right track.看起来你在正确的轨道上。

Your useCity hook does basically 2 things that you can validate in tests:你的useCity钩子基本上做了两件事,你可以在测试中验证:

  1. builds an url建立一个网址
  2. converts the cities to another format将城市转换为另一种格式

You can validate useSWR is called with the correct url by using a spy:您可以使用间谍验证使用正确的 url 调用useSWR

import * as SWR from 'swr';

jest.spyOn(SWR, 'default'); // write this line before rendering the hook.
expect(SWR.default).toHaveBeenCalledWith(expectedUrl, {}); // pass any options that were passed in actual object

You can validate useCities returns correct cities by您可以通过useCities方式验证useCities返回正确的城市

const { cities } = result.current;
expect(cities).toEqual(expectedCities);

I am a frontend developer, is this my responsibility to test that API call?我是一名前端开发人员,这是我测试 API 调用的责任吗?

I think that is up to you to find the answer.我认为这取决于你来寻找答案。 I personally see as my responsibility to test any code that I write--that of course is not a dogma and is context sensitive.我个人认为测试我编写的任何代码是我的责任——这当然不是教条并且是上下文敏感的。

I don't know what this kind of tests are called.我不知道这种测试叫什么。 If someone can tell me the kind of the test I am perfoming, then it will help me google for the solutions如果有人可以告诉我我正在执行的测试类型,那么它将帮助我谷歌寻找解决方案

There might not be a clear answer for this.对此,可能没有明确的答案。 Some people would call it unit testing (since useCities is a "unit").有些人会称之为单元测试(因为useCities是一个“单元”)。 Others might call it integration testing (since you test useCities and useSWR in "integration").其他人可能称之为集成测试(因为您在“集成”中测试useCitiesuseSWR )。

Your best bet would be to google things like "how to test react hooks" or "how to test react components".最好的办法是在谷歌上搜索诸如“如何测试 React 钩子”或“如何测试 React 组件”之类的内容。 The RTL docs are a good place to start. RTL 文档是一个很好的起点。


Extra notes附加说明

I personally almost never test hooks in isolation.我个人几乎从不单独测试钩子。 I find it easier and more intuitive to write integration tests for the components that use the hooks.我发现为使用钩子的组件编写集成测试更容易、更直观。

However, if your hook is going to be used by other projects, I think it makes sense testing them in isolation, like you are doing here.但是,如果您的钩子将被其他项目使用,我认为单独测试它们是有意义的,就像您在这里所做的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 useSWR Hook 返回 undefined - useSWR Hook returns undefined 我应该在自定义钩子中记住函数吗? - Should I memoize functions in custom hook? “在 function 中调用了 useSWR,它既不是 React function 组件,也不是自定义 React Hook 函数”错误 - "useSWR is called in function that is niether a React function component nor a custom React Hook function" Error 当导航参数更新时使用 useSWR 进行 api 调用,并将其值存储在带有 contextAPI 的自定义挂钩上 - Make api call with useSWR when navigation params updates and store his value on custom hook with contextAPI 如何遍历 URL 列表并使用 useSWR 挂钩调用服务器 - How can I iterate over the list of URLs and make a call to the server using useSWR hook 为什么或何时应该在 React 的自定义 Hook 中使用状态? - Why or when should I use state within a custom Hook in React? 我应该记住自定义 React 钩子返回的 object 吗? - Should I memoize the returned object of a custom React hook? useSWR 钩子行为不正常或可能过时的关闭 - useSWR hook behaving erratically or possible stale closure 如何在 React JS 中测试我的自定义 Hook? - How Can I test my custom Hook in React JS? useEffect Hook 的依赖项应该是什么? - What should be the dependencies of useEffect Hook?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM