Jest抛出TypeError:无法读取未定义的属性'fetch'

时间:2017-05-18 10:25:44

标签: reactjs react-native webpack fetch jestjs

我正在尝试使用Jest在我的react / react-native库上运行一些测试(内部只有一些业务逻辑)。

我们正在测试使用获取功能的操作(使用whatwg-fetch进行polyfill)。 我已经添加了whatwg-fetch(感谢Safari)的反应。

每当我尝试运行测试时,我都会收到此错误:

NSString *searchStringWithPattern = [self.searchIngrediants.text stringByReplacingOccurrencesOfString:@" " withString:@"*"];
searchStringWithPattern = [NSString stringWithFormat:@"*%@*", searchStringWithPattern];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ingredientName LIKE[cd] %@)" , searchStringWithPattern];
[fetchRequest setPredicate:predicate];

可能导致此问题的原因是什么?在jest配置中有没有办法避免这种情况?

以下是一些调试文件:

package.json中的Jest配置

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)

Webpack配置:

"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"
]
},

测试文件:

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);
    });
  });

谢谢!

4 个答案:

答案 0 :(得分:0)

我已在规范中使用:

完成
import { fetch } from 'whatwg-fetch';

global.fetch = fetch;

它和Jest一样有效。

答案 1 :(得分:0)

可能会迟到,但这对我有用。

可能的解决方案#1

注意:从React v15.5开始,不推荐使用React.PropTypes。请改用prop-types库。

如果安装npm包prop-types,则它具有isomorphic-fetch作为依赖项。这将使您获取全局。您仍然需要将其导入测试文件。您可能还需要将它从您的linter中排除。

将其添加到测试文件的顶部。

import fetch from 'isomorphic-fetch'

我不需要在测试套件中调用fetch,但我需要让它可用。

如果您使用此方法,我认为您将从您的webpack条目中删除'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"]
  }

这将允许在测试中使用fetch。

我还必须对localStorage使用相同的概念。我保留了Jest无法访问的所有全局变量。

答案 2 :(得分:0)

将针对最新版本的本机,开玩笑和流行音乐升级为我们修复此问题。

答案 3 :(得分:0)

这对我有用。在您需要whatwg-fetch的expo设置文件(node_modules / jest-expo / src / setup.js)中,我将其更改为 require(&#39; fetch-everywhere&#39;)

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

由于某些原因,只有fetch到处都在使用expo和jest。