尝试从单元测试的获取中模拟响应主体

Trying to mock response body from a fetch for a unit test

我对 sinon 和 proxyquire 还很陌生,我想我已经阅读了这里关于 SO 的所有答案,但我仍然没有找到我需要的东西。不管怎样,这是我的代码的净化版本。

const fetch = require('node-fetch');

async function deleteID(id, endpoint) {
  try {
      let url = `${endpoint}/delete/${id}`;
      let res = await fetch(url, { method: 'DELETE' });
      res = await res.json(); // <---- THIS FAILS WHEN fetch IS MOCKED
      // do stuff with res
  } catch (err) {
    logger.error(`Error: ${JSON.stringify(err)}`);
  }
}

它非常简单,它使用节点获取来命中 url,然后在请求成功或失败时执行一些操作。这是我的测试,让我们为获取设置模拟:

const proxyquire = require('proxyquire').noCallThru();
const sinon = require('sinon');

  beforeEach((done) => {

    const validResponse = {
      status: 200,
      data: 'hello, world\n'
    };
    deleteProxy = proxyquire('./delete', {
      'node-fetch': sinon.stub().returns(Promise.resolve(JSON.stringify(validResponse)))
    });
  });

所以 fetch 现在调用 returns validResponse 而不是访问服务器。这是我的测试:

    it.only('should delete', async () => {
    try {
      deleteProxy.deleteID('id', 'endpoint');
    } catch (err) {
      expect(err.message).to.have.lengthOf.at.least(0);
    }
  });

这失败了,因为 res 只是一个具有状态和数据的对象,它不是一个具有 Body 等的正确响应...我们代码的其余部分使用 node-mocks-http 但所有使用该模块的测试都直接命中 url,而不是像我在上面所做的那样通过 fetch 间接命中。

我如何创建模拟响应以适应上述测试,或者我应该使用其他方法吗?

通过查看代码和我使用 sinon 的经验,我会说这不是实际的 HTTP 响应,因此您还必须模拟 json()。 在 beforeEach 方法中:

 const body = {
  status: 200,
  data: 'hello, world\n'
};
var validResponse = { json: () => { return body } };
deleteProxy = proxyquire('./delete', {
  'node-fetch': sinon.stub().returns(Promise.resolve(validResponse))
});

试试 JSON.stringify()

如果它不起作用,请告诉我。