English 中文(简体)
Mock Customs hook in response 18 with jest 29
原标题:Mock custom hook in react 18 with jest 29

目前,我试图测试我使用习俗的成分,但我似乎无法人工改变该构成部分中使用的习惯。

我的法典如下:

src/components/movies/MovieDetail.tsx

import { useParams } from  react-router-dom ;

import { Movie } from  ../../models/Movie ;
import { useFetch } from  ../../hooks/useFetch ;
import { SCYoutubeVideoPlayer } from  ../YoutubeVideoPlayer ;
import { SCTagList } from  ../tags/TagList ;
import { SCActorList } from  ../actors/ActorList ;
import { SCMovieSpecs } from  ./MovieSpecs ;
import { SCServerError } from  ../errors/ServerError ;
import { SCLoading } from  ../loading/Loading ;

import styles from  ./MovieDetail.module.scss ;

export const SCMovieDetail = () => {
  const { slug } = useParams();
  const { error, loading, data: movie } = useFetch<Movie>({ url: `http://localhost:3000/movies/${slug}` });

  if (error) {
    return <SCServerError error={error} />;
  }

  if (loading || movie === undefined) {
    return <SCLoading />;
  }

  return (
    <>
      <section className={`${styles.spacing} ${styles.container}`}>
        <h2>{movie.title}</h2>
        <SCMovieSpecs movie={movie} />
      </section>

      <section className={styles[ trailer-container ]}>
        <div>
          <SCYoutubeVideoPlayer src={movie.trailer} />
        </div>
      </section>

      <section className={`${styles.spacing} ${styles.container}`}>
        <SCTagList tags={movie.tags} />
        <div className={styles.description}>
          <p>{movie.description}</p>
        </div>
        <SCActorList actors={movie.cast} />
      </section>
    </>
  );
};

src/components/movies/MovieDetail.test.tsx

import renderer from  react-test-renderer ;
import { render, screen } from  @testing-library/react ;
import { MemoryRouter } from  react-router-dom ;

import { SCMovieDetail } from  ./MovieDetail ;

describe( SCMovieDetail , () => {
  const componentJSX = () => {
    return (
      <MemoryRouter>
        <SCMovieDetail />
      </MemoryRouter>
    );
  };

  it( Should match snapshot , () => {
    const component = renderer.create(<SCMovieDetail />);
    const tree = component.toJSON();
    expect(tree).toMatchSnapshot();
  });

  it( Should render error , () => {
    jest.mock( ../../hooks/useFetch );

    render(componentJSX());

    expect(screen.getByText( Hello! )).toBeInTheDocument();
  });
});

<>斯特凡>

import { useFetchPayload, useFetchProps } from  ../useFetch ;

export const useFetch = <T>({ url, method =  GET  }: useFetchProps): useFetchPayload<T> => {
  let data: T | undefined = undefined;
  let error: string | undefined = undefined;
  let loading = false;

  console.log( MOCKED!!! );
  console.log( MOCKED!!! );
  console.log( MOCKED!!! );

  switch (url) {
    case  success :
      data = {} as T;
      break;
    case  error :
      error = `${method} request failed`;
      break;
    case  loading :
      loading = true;
      break;
  }

  return { data, error, loading };
};

src/hooks/useFetch.ts

import { useEffect, useState } from  react ;

export interface useFetchProps {
  url: string;
  method?:  GET  |  POST  |  UPDATE  |  PATCH  |  DELETE ;
}

export interface useFetchPayload<T> {
  data?: T;
  error?: string;
  loading: boolean;
}

export const useFetch = <T>({ url, method =  GET  }: useFetchProps): useFetchPayload<T> => {
  const [data, setData] = useState<T | undefined>(undefined);
  const [error, setError] = useState<string | undefined>(undefined);
  const [loading, setLoading] = useState(false);

  console.log( REAL!!! );
  console.log( REAL!!! );
  console.log( REAL!!! );

  useEffect(() => {
    const abortController = new AbortController();

    const fetchData = async () => {
      try {
        const response = await fetch(url, { method, signal: abortController.signal });
        if (!response || !response.ok) {
          throw new Error( Request failed! );
        }
        const json = await response.json();
        setData(json);
      } catch (error: unknown) {
        if (error instanceof DOMException && error.name ==  AbortError ) {
          return;
        }
        const customError = error as Error;
        setError(customError.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    return () => abortController.abort();
  }, [url, method]);

  return { data, error, loading };
};

名录结构迅速超支;

src/
|-- ...
|-- components/
|   | ...
|   |-- movies/
|   |   |-- MovieDetail.tsx
|   |   |-- MovieDetail.test.tsx 
|   |   |-- ...
|-- hooks/
|   |-- __mocks__/
|   |   |-- useFetch.tsx
|   |-- useFetch.tsx
|   |-- ...
|-- ...

我已经搜索了多个中继站和其他地点,但仍未找到答案。 希望你能帮助我找到失踪人员! I m 采用React 18, Jest 29。 目标是在Im 仍在学习后,结合Jest,使用最低数量的 no子和重试图书馆。 如果能够重新使用模拟器,那么最好使用mocks目录,而不是每一次在我的测试中直接模拟执行。

问题回答

我更喜欢“条码”。 而不是useFetch

由于仅仅篡改<代码>使用Fetch的回报价值就将破坏其功能,因此内部使用的 h功能,例如<代码>使用国家和<代码>不适用无机运行。 该构成部分将多次通过<条码>国家、实际实施<条码>(>使用代码<>>>>>>/代码>。

为了简明起见,我将直接 mo弄手法,而不是引入msw。 仅举几个例子,说明:

MovieDetail.tsx:

import React from  react ;

import { useFetch } from  ./hooks/useFetch ;

export const SCMovieDetail = () => {
  const movieQuery = useFetch<string>({ url: `http://localhost:3000/movies/1` });

  console.log( ? ~ SCMovieDetail ~ movieQuery: , movieQuery);
  return (
    <>
      <section>{movieQuery.data}</section>
    </>
  );
};

hooks/useFetch.ts:

import { useEffect, useState } from  react ;

export interface useFetchProps {
  url: string;
  method?:  GET  |  POST  |  UPDATE  |  PATCH  |  DELETE ;
}

export interface useFetchPayload<T> {
  data?: T;
  error?: string;
  loading: boolean;
}

export const useFetch = <T>({ url, method =  GET  }: useFetchProps): useFetchPayload<T> => {
  const [data, setData] = useState<T | undefined>(undefined);
  const [error, setError] = useState<string | undefined>(undefined);
  const [loading, setLoading] = useState(false);

  console.log( REAL!!! );
  console.log( REAL!!! );
  console.log( REAL!!! );

  useEffect(() => {
    const abortController = new AbortController();

    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await fetch(url, { method, signal: abortController.signal });
        if (!response || !response.ok) {
          throw new Error( Request failed! );
        }
        const json = await response.json();
        setData(json);
      } catch (error: unknown) {
        if (error instanceof DOMException && error.name ==  AbortError ) {
          return;
        }
        const customError = error as Error;
        setError(customError.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    return () => abortController.abort();
  }, [url, method]);

  return { data, error, loading };
};

MovieDetail.test.tsx:

import React from  react ;
import { render, screen } from  @testing-library/react ;
import  @testing-library/jest-dom ;

import { SCMovieDetail } from  ./MovieDetail ;

describe( SCMovieDetail , () => {
  it( Should render data , async () => {
    jest.spyOn(global,  fetch ).mockResolvedValue({
      ok: true,
      json: jest.fn().mockResolvedValue( Hello! ),
    } as unknown as Response);

    render(<SCMovieDetail />);

    expect(await screen.findByText( Hello! )).toBeInTheDocument();
  });
});

测试结果:

  console.log
    REAL!!!

      at log (stackoverflow/78474280/hooks/useFetch.ts:19:11)

  console.log                                                                                                                                                                                                                                            
    REAL!!!                                                                                                                                                                                                                                              

      at log (stackoverflow/78474280/hooks/useFetch.ts:20:11)

  console.log                                                                                                                                                                                                                                            
    REAL!!!                                                                                                                                                                                                                                              

      at log (stackoverflow/78474280/hooks/useFetch.ts:21:11)

  console.log                                                                                                                                                                                                                                            
    ? ~ SCMovieDetail ~ movieQuery: { data: undefined, error: undefined, loading: false }                                                                                                                                                               

      at log (stackoverflow/78474280/MovieDetail.tsx:9:11)

  console.log
    REAL!!!

      at log (stackoverflow/78474280/hooks/useFetch.ts:19:11)

  console.log                                                                                                                                                                                                                                            
    REAL!!!                                                                                                                                                                                                                                              

      at log (stackoverflow/78474280/hooks/useFetch.ts:20:11)

  console.log                                                                                                                                                                                                                                            
    REAL!!!                                                                                                                                                                                                                                              

      at log (stackoverflow/78474280/hooks/useFetch.ts:21:11)

  console.log                                                                                                                                                                                                                                            
    ? ~ SCMovieDetail ~ movieQuery: { data: undefined, error: undefined, loading: true }                                                                                                                                                                

      at log (stackoverflow/78474280/MovieDetail.tsx:9:11)

  console.log
    REAL!!!

      at log (stackoverflow/78474280/hooks/useFetch.ts:19:11)

  console.log                                                                                                                                                                                                                                            
    REAL!!!                                                                                                                                                                                                                                              

      at log (stackoverflow/78474280/hooks/useFetch.ts:20:11)

  console.log
    REAL!!!

      at log (stackoverflow/78474280/hooks/useFetch.ts:21:11)

  console.log
    ? ~ SCMovieDetail ~ movieQuery: { data:  Hello! , error: undefined, loading: false }

      at log (stackoverflow/78474280/MovieDetail.tsx:9:11)

 PASS  stackoverflow/78474280/MovieDetail.test.tsx
  SCMovieDetail
    √ Should render error (98 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.183 s
Ran all test suites related to changed files.




相关问题
SoapUI Groovy 方言

我试图阅读即将提出的申请,并根据请求中价值分立的3.0作出模拟反应。 我为此使用了以下大写。

Mocking Entity Context in EF4

I am using VS2010 B2 and EF4 B2 and trying to use Rhino Mocks to mock the entity context generated by EEF. var context = MockRepository.GenerateMock<SomeDBEntities>(); IObjectSet<TxMode> ...

Google Mock for iPhone development?

I have an interesting situation where I am refactoring a bunch of ObjC iPhone code to create a C++ API. I m a novice to C++ and looking into C++ mocking frameworks to augment the work I d done using ...

StrucutureMap RhinoMock Record/Playback, Example needed

I m looking for some examples on how to do the following Mock Tests using StructureMap or Unity with NUnit. I have the following code structure public interface IDAL { List<Model> Method1(...

Easiest way to deal with sample data in Java web apps?

I m writing a Java web app in my free time to learn more about development. I m using the Stripes framework and eventually intend to use hibernate and MySQL For the moment, whilst creating the pages ...

Elegant design of simulating a read-only object

I am currently developing an GUI to an embedded system. (I am using GUI to descripe my app opposed to interface to avoid confusion with the progamatic meaning) Context I have created a class which ...

热门标签