1

我正在尝试对一个简单的函数进行单元测试,该函数发送一个 get 请求,接收一个响应,然后返回一个带有成功或失败消息的 promise 对象。以下是函数:

module.exports.hello = async (event, context) => {
  return new Promise((resolve, reject) => {
    fetch("https://httpstat.us/429", { headers: { 'Content-Type': 'application/json' } }).then(response => {
      console.log(response);
      if (response.status == 200) {
        return response;
      } else {
        throw Error(response.status + ": " + response.statusText);
      }
    }).then(tokenData => {
      resolve({ status: 200, body: JSON.stringify({ statusText: 'Success' }) });
    }).catch(error => {
      reject(error.message);
    });
  });
};

在进行单元测试时,我使用 fetch-mock 来模拟对 api 的调用并具有自定义响应。以下是代码:

it('hello returns failure message', (done) => {
    fetchMock.get('*',  {
        status: 429,
        statusText: "Too Many Nothings",
        headers: { 'Content-type': 'application/json' }
     });

    edx.hello(null, null).catch(error => {
        expect(error).to.equal('429: Too Many Requests');
    }).then(() => {
        done();
    }).catch(error => {
        done(error);
    });
});

但是这段代码并没有模拟获取请求,因为当我打印响应文本时,它是“太多请求”,它作为 API 的响应发送,而不是被模拟的“太多无”。我是 NodeJS 的新手。请告诉我我做错了什么。

4

1 回答 1

0

如果你使用node-fetch包,它在 Node.js 的全局范围内不可用。为了完成fetch-mock工作,您必须将 fetch 分配给global对象(例如,通过import "node-fetch";代替import fetch from "node-fetch";)或使 fetch 可注入到您的测试方法。

来自http://www.wheresrhys.co.uk/fetch-mock/#usageglobal-non-global

全局或非全局

fetch 可以由您的代码全局或本地使用。确定哪一个适用于您的代码库很重要,因为它会影响您使用 fetch-mock 的方式

全局获取

在以下场景中 fetch 将是一个全局的

  • 在浏览器中使用本机 fetch(或 polyfill)时
  • 在 Node.js 进程中将 node-fetch 分配给 global 时(有时在同构代码库中使用的模式)

默认情况下,fetch-mock 假定 fetch 是全局的,因此一旦您需要 fetch-mock,就不需要进行更多设置。非全局提取库

在以下情况下 fetch 不会是全局的

  • 在 Node.js 中使用 node-fetch 而不分配给全局
  • 在浏览器中使用 fetch-ponyfill
  • 使用在内部使用 fetch-ponyfill 的库
  • 一些构建设置会导致非全局提取,尽管情况可能并不总是很明显

sandbox() 方法返回一个函数,该函数可用作 fetch 的替代品。将其传递到您选择的模拟库中。sandbox() 返回的函数暴露了所有的 fetch-mock 方法,例如

const fetchMock = require('fetch-mock');
const myMock = fetchMock.sandbox().mock('/home', 200); // pass myMock in to your application code, instead of fetch, run it, then...
expect(myMock.called('/home')).to.be.true;
于 2019-05-24T01:17:22.213 回答