Выдача шутки TypeError: невозможно прочитать свойство fetch of undefined

Я пытаюсь запустить несколько тестов с Jest в моей собственной библиотеке реакции / реакции (внутри только некоторая бизнес-логика).

Мы тестируем действия, которые используют функцию выборки (полифил с whatwg-fetch). Я добавил whatwg-fetch (спасибо Safari) для реакции.

Всякий раз, когда я пытаюсь запустить тест, я получаю эту ошибку:

TypeError: Cannot read property 'fetch' of undefined

  at node_modules/whatwg-fetch/fetch.js:4:11
  at Object.<anonymous> (node_modules/whatwg-fetch/fetch.js:461:3)
  at Object.<anonymous> (node_modules/jest-expo/src/setup.js:138:416)

Что может вызвать эту проблему? Есть ли способ избежать этого в конфигурации шутки?

Вот несколько файлов для отладки:

Конфигурация Jest в package.json

"jest": {
"preset": "jest-expo",
"moduleFileExtensions": [
  "js",
  "jsx",
  "ts",
  "tsx"
],
"verbose": true,
"transform": {
  "^.+\\.(js|ts|tsx)$": "<rootDir>/node_modules/babel-jest"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
  "\\.snap$",
  "<rootDir>/node_modules/",
  "<rootDir>/dist/"
],
"transformIgnorePatterns": [
  "node_modules/?!react-native"
]
},

Конфигурация Webpack:

const config = {
entry: [
    'whatwg-fetch',
    __dirname + '/src/index.ts',
],
devtool: 'source-map',
output: {
    path: path.join(__dirname, '/dist'),
    filename: 'index.js',
    library: 'checkinatwork-module',
    libraryTarget: 'umd',
    umdNamedDefine: true,
},
module: {
    loaders: [
        { test: /\.(tsx|ts)?$/, loader: 'ts-loader', exclude: /node_modules/ },
    ],
},
resolve: {
    modules: [
        './src',
        'node_modules',
    ],
    extensions: ['.js', '.ts', '.jsx', '.tsx', 'json'],
},
plugins: [
],
};

Тестовый файл:

import expect from 'expect';
import * as actions from '../../src/components/Checkin/checkin.action';
import * as reducers from '../../src/components/Checkin/checkin.reducer';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import nock from 'nock';

const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);

describe('=> ADD CHECKIN ACTIONS', () => {
  describe('- REQUEST', () => {
    it('Action: ADD_CHECKIN_REQUEST should request addCawCheckin', () => {
      const expectedAction = {
        type: actions.ADD_CHECKIN_REQUEST,
        isFetching: true,
      };
      expect(actions.addCheckinRequest())
        .toEqual(expectedAction);
    });
    it('Reducer: newCheckin should trigger ADD_CHECKIN_REQUEST and initiate loading', () => {
      const expectedState = {
        isFetching: true,
        status: null,
      };
      expect(reducers.newCheckin(reducers.newCheckinDefaultState, actions.addCheckinRequest()))
        .toEqual(expectedState);
    });
  });

Файл действия:

export const getCheckins = (sessionId, date, url, isRefresh) => {
  const config = {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      sessionId: {sessionId},
      date: {date},
    }),
  };

  return dispatch => {
    if (!isRefresh) {
      dispatch(getCheckinsRequest());
    }
    return fetch(url + 'getCAWCheckIns', config)
      .then(response => response.json())
      .then(({ checkins }) => {
        dispatch(getCheckinsSuccess(checkins));
      }).catch(err => {
        dispatch(getCheckinsError('Get checkins failed'));
        console.error('Get checkins failed: ', err);
      });
  };
};

Спасибо!


person clems36    schedule 18.05.2017    source источник


Ответы (4)


Я сделал это в спецификации с помощью:

import { fetch } from 'whatwg-fetch';

global.fetch = fetch;

И с Jest это сработало, как и ожидалось.

person Samuli Hakoniemi    schedule 18.05.2017
comment
У меня это не работает. Я добавил импорт поверх всех тестовых файлов. - person clems36; 18.05.2017

может опоздать на игру, но у меня это сработало.

Возможное решение # 1

Примечание. React.PropTypes устарел в React v15.5. Вместо этого используйте библиотеку типов опор.

Если вы установите prop-types пакета npm, он будет иметь isomorphic-fetch в качестве зависимости. Это даст вам выборку как глобальный. Вам все равно нужно будет импортировать его в тестовый файл. Возможно, вам придется исключить его и из линтера.

добавьте это в начало тестового файла.

import fetch from 'isomorphic-fetch'

Мне не нужно было вызывать fetch в тестовом наборе, но мне нужно было сделать его доступным.

Если вы воспользуетесь этим подходом, я думаю, вы удалите 'whatwg-fetch', из записи в веб-пакете.

Надеюсь это поможет

Обновлено: возможное решение №2

Используя приведенный выше пример @zvona, но создайте папку MOCKS в своем приложении. затем файл /globalMock.js. Возможно, вы неправильно его настроили.

   __MOCKS__/globalMock.js

   // use one of these imports 

   import { fetch } from 'whatwg-fetch' // if you want to keep using the polyfill

   import { fetch } from 'isomorphic-fetch' // from a dependency node module that I spoke of in the previous solution.

   global.fetch = fetch

Теперь в package.json

добавьте это в свою конфигурацию Jest:

"jest": {
    "verbose": true,
    "rootDir": "app",
    "setupFiles": ["<rootDir>/__MOCKS__/globalMock.js"]
  }

это позволит использовать выборку в ваших тестах.

Мне также пришлось использовать ту же концепцию для localStorage. Где я храню все свои глобальные объекты, к которым у Jest нет доступа.

person J. Parrish    schedule 22.05.2017
comment
Совсем не поздно! Я ди, как вы сказали, но все еще проблема ... Я также попытался поставить isomorphic-fetch в качестве своей записи в веб-пакете, но это ничего не изменило, сообщение об ошибке осталось прежним. - person clems36; 23.05.2017
comment
Добавил обновление, также только что видел это в fetch документах github: если этот полифилл не работает в Среды Node.js, что ожидается, потому что этот проект предназначен только для веб-браузеров. Вы должны убедиться, что ваше приложение не пытается упаковать и запустить это на сервере. - person J. Parrish; 23.05.2017
comment
Привет, я внес эти изменения, но все равно не повезло. Я думаю о переходе от fetch к axios в качестве решения ... Спасибо за вашу помощь. - person clems36; 24.05.2017

Обновление react-native, jest и babel-jest до последних версий устранило эту проблему для нас.

person Freewalker    schedule 06.06.2017

Это сработало для меня. В вашем файле настройки expo (node_modules / jest-expo / src / setup.js), где требуется whatwg-fetch, я изменил это требование на require ('fetch-везде')

const { Response, Request, Headers, fetch } = 
  require('fetch-everywhere');
global.Response = Response;
global.Request = Request;
global.Headers = Headers;
global.fetch = fetch;

Почему-то везде только fetch работал с expo и jest.

person Jolaade Adewale    schedule 23.05.2018