2017-05-18 193 views
2

我試圖用Jest在我的react/react-native庫(只有一些業務邏輯裏面)上運行一些測試。Jest拋出TypeError:無法讀取未定義的屬性'fetch'

我們正在測試使用獲取函數(使用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); 
     }); 
    }; 
}; 

謝謝!

回答

0

我已經做到了在規範

import { fetch } from 'whatwg-fetch'; 

global.fetch = fetch; 

,它已與玩笑預期工作。

+0

它不適合我。我在測試文件中添加了導入。 – clementino36

0

可能會遲到比賽,但這對我有效。

可能的解決方法#1

注:React.PropTypes被棄用陣營V15.5的。請改用prop-types庫。

如果您安裝npm包prop-types,它將isomorphic-fetch作爲依賴項。這會讓你獲取全局。您仍然需要將其導入到測試文件中。您可能還需要將其從您的linter中排除。

將其添加到測試文件的頂部。

import fetch from 'isomorphic-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": { 
    "verbose": true, 
    "rootDir": "app", 
    "setupFiles": ["<rootDir>/__MOCKS__/globalMock.js"] 
    } 

這將允許使用在測試中獲取的。

我也必須對localStorage使用相同的概念。我在哪裏保留了Jest無法訪問的所有全局變量。

+0

不遲到!我di如你所說,但仍然有問題...我也嘗試把isomorphic-fetch作爲我的webpack條目,但它沒有改變任何東西,錯誤信息仍然是一樣的。 – clementino36

+0

添加了一個更新,在[fetch](https://github.com/github/fetch)github文檔中也看到了這一點:「如果這個polyfill在Node.js環境下不起作用,那是預期的,因爲這個項目僅適用於Web瀏覽器,您應該確保您的應用程序不會嘗試在服務器上進行打包和運行。「 –

+0

嗨,我做了這些改變,但仍然沒有運氣。我正在考慮從提取到axios作爲解決方案...感謝您的幫助。 – clementino36

0

將react-native,jest和babel-jest升級到最新版本爲我們解決了這個問題。

相關問題