source

Jest를 사용한 새로운 리액트라우터 후크를 사용한history.push의 모의 방법

ittop 2023. 4. 2. 11:53
반응형

Jest를 사용한 새로운 리액트라우터 후크를 사용한history.push의 모의 방법

나는 조롱하려고 한다.history.push신내부useHistory에 접속하다react-router및 사용@testing-library/react첫 번째 답변과 같이 모듈을 조롱했습니다.새로운 리액트 라우터 후크를 사용하여 컴포넌트를 테스트하는 방법

그래서 하고 있습니다.

//NotFound.js
import * as React from 'react';
import { useHistory } from 'react-router-dom';


const RouteNotFound = () => {
  const history = useHistory();
  return (
    <div>
      <button onClick={() => history.push('/help')} />
    </div>
  );
};

export default RouteNotFound;
//NotFound.test.js
describe('RouteNotFound', () => {
  it('Redirects to correct URL on click', () => {
    const mockHistoryPush = jest.fn();

    jest.mock('react-router-dom', () => ({
      ...jest.requireActual('react-router-dom'),
      useHistory: () => ({
        push: mockHistoryPush,
      }),
    }));

    const { getByRole } = render(
        <MemoryRouter>
          <RouteNotFound />
        </MemoryRouter>
    );

    fireEvent.click(getByRole('button'));
    expect(mockHistoryPush).toHaveBeenCalledWith('/help');
  });
})

그렇지만mockHistoryPush불리지 않습니다.내가 뭘 잘못하고 있지?

사용하다jest.mockin module scope는 자동으로 코드 블록의 맨 위로 올라갑니다.그러면 조롱된 버전을 얻을 수 있습니다.react-router-domNotFound.jsx파일 및 테스트 파일.

게다가, 우린 그저 조롱하고 싶을 뿐이야useHistory훅을 걸기 때문에jest.requireActual()원래 모듈을 가져오고 다른 메서드를 원래 버전으로 유지합니다.

해결책은 다음과 같습니다.

NotFound.jsx:

import React from 'react';
import { useHistory } from 'react-router-dom';

const RouteNotFound = () => {
  const history = useHistory();
  return (
    <div>
      <button onClick={() => history.push('/help')} />
    </div>
  );
};

export default RouteNotFound;

NotFound.test.jsx:

import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { render, fireEvent } from '@testing-library/react';
import RouteNotFound from './NotFound';

const mockHistoryPush = jest.fn();

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    push: mockHistoryPush,
  }),
}));

describe('RouteNotFound', () => {
  it('Redirects to correct URL on click', () => {
    const { getByRole } = render(
      <MemoryRouter>
        <RouteNotFound />
      </MemoryRouter>,
    );

    fireEvent.click(getByRole('button'));
    expect(mockHistoryPush).toHaveBeenCalledWith('/help');
  });
});

100% 적용 범위에서의 유닛 테스트 결과:

PASS  src/stackoverflow/58524183/NotFound.test.jsx
  RouteNotFound
    ✓ Redirects to correct URL on click (66ms)

--------------|----------|----------|----------|----------|-------------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files     |      100 |      100 |      100 |      100 |                   |
 NotFound.jsx |      100 |      100 |      100 |      100 |                   |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.133s, estimated 11s

소스 코드: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58524183

당신은 실제로 조롱할 필요가 없다.react-router-dom(최소한 v5의 경우)다양한 테스트 툴을 제공하고 있습니다.https://v5.reactrouter.com/web/guides/testing

이력이 실제로 변경되었는지 확인하려면createMemoryHistory내용물을 검사합니다.

import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Menu } from './Menu';
import { createMemoryHistory } from 'history'
import { Router } from 'react-router-dom';

test('triggers path change', () => {
  const history = createMemoryHistory();

  render(
    <Router history={history}>
      <Menu />
    </Router>
  );

  const aboutItem = screen.getByText('About');
  expect(aboutItem).toBeInTheDocument();

  userEvent.click(aboutItem);
  expect(history.length).toBe(2);
  expect(history.location.pathname).toBe('/about');
});

이게 도움이 될 수도 있어요.jest.fn()사용하여 history.push()를 조롱할 수 있습니다.

const historyMock = { push: jest.fn() }   

expect(historyMock.push.mock.calls[0]).toEqual([
        {
          pathname: "/profile", // URL
          search: , // search-data
        },
      ]);

언급URL : https://stackoverflow.com/questions/58524183/how-to-mock-history-push-with-the-new-react-router-hooks-using-jest

반응형