Как мне издеваться над react-router-dom, используя jest из каталога __mocks__

#reactjs #unit-testing #react-router #jestjs

#reactjs #модульное тестирование #react-router #jestjs

Вопрос:

У меня есть тест, который проверяет провайдера, который использует react-router 6 useLocation

 "react-router-dom": "^6.0.0-beta.0",
  

Он отлично работает, когда я издеваюсь над файлом

 import React from 'react';
import { render } from '@testing-library/react';
import Categories from './Categories';
import mockCategories from '../../__mocks__/mockCategories';
import ExpenditureProvider from '../../domains/Expenditure/ExpenditureProvider';

jest.mock('react-router-dom', () => {
  const originalModule = jest.requireActual('react-router-dom');

  return {
    __esModule: true,
    ...originalModule,
    useNavigate: jest.fn(),
    useLocation: jest.fn().mockReturnValue({ pathname: '/'}),
  };
});

describe('Categories', () => {
  test('should render Categories component', () => {
    const categories = render(
      <ExpenditureProvider>
        <Categories categories={mockCategories}/>
      </ExpenditureProvider>
      );
  });
});
  

но когда я пытаюсь поместить этот __mocks__ каталог в каталог, я получаю эту ошибку

 Error: Uncaught [Error: useLocation() may be used only in the context of a <Router> component.]
  
 // __mocks__/react-router-dom.js

const originalModule = jest.requireActual('react-router-dom');
export default {
  __esModule: true,
  ...originalModule,
  useLocation: jest.fn().mockReturnValue({ pathname: '/'}),
  useNavigate: jest.fn()
}

  

Макет файла находится в корневом каталоге с node_modules

 ├── __mocks__
│   └── react-router-dom.js
├── node_modules
├── src
│ 
  

То, что я хотел бы сделать, это только макет из __mocks__ каталога, потому что этот макет используется в нескольких тестах

Комментарии:

1. Пожалуйста, обновите вопрос точным сообщением об ошибке вместо неопределенного оператора it doesn’t work , это может помочь пользователям, у которых есть подобная проблема.

2. @EstusFlask Это ошибка, которую я получаю Ошибка: Uncaught [Ошибка: useLocation() может использоваться только в контексте компонента <Router> .], вы прочитали вопрос ?! Я переместил его, чтобы сделать его более понятным

3. Спасибо. Было неясно, относится ли ошибка к сценарию, в котором вы использовали __mocks__ , а не вообще не издевались.

Ответ №1:

Макет неправильно экспортирует содержимое модуля как default вместо * . Невозможно * динамически определять экспорт с export помощью синтаксиса модуля ES. Вместо этого необходимо использовать CommonJS export, он работает так же, как jest.mock return, __esModule: true и работает как * ESM export:

 const originalModule = jest.requireActual('react-router-dom');
module.exports = {
  __esModule: true,
  ...originalModule,
  useLocation: jest.fn().mockReturnValue({ pathname: '/'}),
  useNavigate: jest.fn()
}
  

Комментарии:

1. Это была единственная проблема в опубликованном вами коде. Что касается ошибки, макет не распознается. Jest изначально ожидает его вместе с node_modules, как и вы. Если вы используете проект create-react-app, перейдите __mocks__ к src , см. github.com/facebook/create-react-app/issues/7539

2. Спасибо! это была другая половина проблемы, как только я переместил ее, src она сработала, и, как вы заявили, она не работает с экспортом по умолчанию, спасибо, вы потрясающие