【问题标题】:fetch-mock mocking all requestsfetch-mock 模拟所有请求
【发布时间】:2017-01-26 07:34:30
【问题描述】:

我正在使用 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 未捕获错误:没有为 GET 定义回退响应到 http://localhost:3000/api/session” 这是应用程序中发出的第一个请求。

不知道为什么 fetch-mock 会模拟所有请求。在 chrome 控制台上进行评估时,makeRequest 函数上的 fetch 值是 fetch-mock 函数,但据我所知这是正确的。

顺便说一句,我不是在测试环境,我正在开发,因为我需要模拟我的后端,因为它还没有完成。

知道为什么会这样吗?

提前致谢

【问题讨论】:

    标签: reactjs webpack mocking fetch fetch-mock


    【解决方案1】:

    这个问题是因为fetch-mock的主要目标是帮助测试。在测试环境中,如果您在调度任何非模拟调用时获得异常,则更好。

    但是,您可以添加一个委托给原始fetchcatch 处理程序,以便将任何非模拟请求传递给真正的提取。类似于以下内容:

    /* 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 有一个 greed 属性,设置为

    • 好 - 无与伦比的呼叫响应 200
    • 错误 - 不匹配的调用错误
    • 无 - 允许不匹配的调用使用本机 fetch 和网络

    现在已被 .catch() 方法取代,该方法接受相同的 响应类型作为对 .mock(matcher, response) 的正常调用。它可以 还可以使用任意函数来完全自定义行为 无与伦比的通话。它是可链接的,可以在之前或之后调用 对 .mock() 的其他调用。检查不匹配调用的 api 仍然存在 不变。

    https://github.com/wheresrhys/fetch-mock/blob/master/V4_V5_UPGRADE_NOTES.md#handling-unmatched-calls-greed

    【讨论】:

    • 谢谢老哥,就这样
    【解决方案2】:

    从 fetch-mock v.6.5 开始,有一个名为 fallbackToNetwork 的新配置属性允许您控制 fetch-mock 如何处理未处理(不匹配)的调用

    http://www.wheresrhys.co.uk/fetch-mock/#usageconfiguration

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2019-06-22
      • 2017-11-27
      相关资源
      最近更新 更多