Принуждать насмехаться над всеми запросами
Я использую fetch-mock для того, чтобы смоделировать некоторые запросы к серверу. Здесь все запросы сделаны:
import fetchMock from 'fetch-mock'
import initialState from 'src/initial-state'
if (process.env.NODE_ENV === 'development') {
fetchMock.post('/some/endpoint', initialState.entities.multichannelEngagement)
}
Но не только эта конечная точка является ложной, но и все запросы, сделанные с помощью isomorphic-fetch
import 'isomorphic-fetch'
export function makeRequest(endpoint, config = {}) {
return window.fetch(endpoint, config)
.then(response => {
return response.json()
.then(json => ({ json, response }))
.catch(() => ({ response }))
})
.then(({ json, response }) => {
if (!response.ok) {
throw json ? json : new Error(response.statusText)
} else {
return json
}
})
.catch((e) => {
return Promise.reject(e)
})
}
Мой webpack.config.js выглядит следующим образом:
import path from 'path'
import dotenv from 'dotenv'
import webpack from 'webpack'
import info from './package.json'
const resolvePath = p => path.join(__dirname, p)
const __DEV__ = process.env.NODE_ENV !== 'production'
const { parsed: env } = dotenv.load()
env.NODE_ENV = process.env.NODE_ENV
Object.keys(env).forEach(k => env[k] = JSON.stringify(env[k]))
const config = {
name: info.name,
entry: {
app: 'src/index',
vendor: Object.keys(info.dependencies)
},
output: {
path: __DEV__ ? resolvePath('public') : resolvePath('../analytics-server/server/public'),
filename: '/js/[name].js',
publicPath: '/',
debug: __DEV__,
pathinfo: __DEV__
},
module: {
preLoaders: [{
// NOTE: Run linter before transpiling
test: /\.js$/,
loader: 'eslint-loader',
exclude: /node_modules/
}],
loaders: [{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
// TODO: Remove after upgrading to webpack 2
test: /\.json$/,
loader: 'json'
}]
},
resolve: {
alias: {
src: resolvePath('src'),
core: resolvePath('src/core'),
components: resolvePath('src/components'),
modules: resolvePath('src/modules'),
services: resolvePath('src/services'),
resources: resolvePath('src/resources'),
locales: resolvePath('src/locales')
},
// NOTE: Empty string to properly resolve when providing extension
// TODO: Remove after upgrading to webpack 2
extensions: ['', '.js']
},
plugins: [
// NOTE: `NoErrorsPlugin` causes eslint warnings to stop the build process
// new webpack.NoErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin('commons', '/js/commons.js'),
new webpack.DefinePlugin({ process: { env } })
// new webpack.NormalModuleReplacementPlugin( /^fetch-mock$/, path.resolve( __dirname, 'node_modules', 'fetch-mock/src/client.js' ) )
],
eslint: {
configFile: resolvePath('.eslintrc')
}
}
if (__DEV__) {
config.devtool = 'source-map'
config.devServer = {
contentBase: 'public',
// NOTE: Options `inline` and `hot` shall be passed as CLI arguments
// inline: true,
// hot: true,
historyApiFallback: true
}
} else {
config.plugins.push(...[
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: true,
acorn: true
})
])
}
export default config
Ошибка, которую я получаю при запуске приложения: "fetch-mock.js:93 Uncaught Error: для GET не определен запасной ответ для http://localhost:3000/api/session", который является первым запросом, сделанным в приложении.
Понятия не имею, почему fetch-mock высмеивает все запросы. При оценке на консоли Chrome значение fetch в функции makeRequest является функцией fetch-mock, но, насколько я знаю, это правильно.
Кстати, я не в тестировании env, я в разработке, потому что мне нужен мой бэкенд, потому что это еще не сделано.
Есть идеи, почему это происходит?
заранее спасибо
1 ответ
Проблема вызвана тем, что fetch-mock
Основная цель - помочь с тестированием. В тестовой среде лучше, если вы получите исключение для любых немодерируемых вызовов, отправляемых.
Однако вы можете добавить catch
обработчик, который делегирует оригинал fetch
Таким образом, любой немодальный запрос передается в реальный выбор. Что-то вроде следующего:
/* FAKE FETCH ME */
fetchMock.get('/session', function getSession(url, opts) {
const jwt = extractToken(opts)
if (!jwt || jwt !== fakeToken) {
return delay({
status: 401,
body: JSON.stringify({
details: 'Unauthorized'
})
})
}
return delay({
status: 200,
body: JSON.stringify({
success: true,
data: fakeUserDetails
})
})
})
.catch(unmatchedUrl => {
// fallover call original fetch, because fetch-mock treats
// any unmatched call as an error - its target is testing
return realFetch(unmatchedUrl)
})
В библиотеке была опция для этого, но она была удалена в V5. Смотрите документацию здесь:
В предыдущих версиях fetch-mock имел свойство жадности, установленное на
- хорошо - непревзойденные звонки отвечают 200
- плохо - ошибка несогласованных звонков
- none - разрешить несогласованным вызовам использовать собственную выборку и сеть
Теперь он был заменен методом.catch(), который принимает те же типы ответов, что и обычный вызов.mock(matcher, response). Также может потребоваться произвольная функция для полной настройки поведения несогласованных вызовов. Он является цепным и может быть вызван до или после других вызовов.mock(). API для проверки на несогласованные вызовы остается неизменным.
Начиная с версии fetch-mock v.6.5, есть новое свойство конфигурации, называемое fallbackToNetwork
что позволяет вам контролировать, как необработанные (несогласованные) вызовы должны обрабатываться fetch-mock