node.js - 用 Jest 方式模拟 Node 获取,创建一个用于模拟的响应对象

标签 node.js unit-testing jestjs mocking node-fetch

我正在尝试创建用于 Jest 响应对象,我似乎无法获得正确的语法。

初始化,

jest.mock('node-fetch')
const fetch = require('node-fetch')
const { Response, Headers } = jest.requireActual('node-fetch')

// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class
const meta = {
  'Content-Type': 'application/json',
  'Accept': '*/*',
  'Breaking-Bad': '<3'
}
// You can in fact use any iterable objects, like a Map or even another Headers
const headers = new Headers(meta)
const copyOfHeaders = new Headers(headers)

const ResponseInit = {
  status: 200,
  statusText: 'fail',
  headers: headers
}

通过基本测试

  test('Basic Test', async () => {
    const token = ''
    const getDocList = new Response(JSON.stringify(downloadDocumentData), ResponseInit)
    fetch.mockResolvedValueOnce(Promise.resolve(getDocList))
    await module.doSomething('mock', token)
      .then( async(res) => {
        await expect(res.data).toEqual(Object)
      })
  }, 5000)

我收到一个错误是
     FetchError {
        message:
         'invalid json response body at  reason: Unexpected token H in JSON at position 2',
        type: 'invalid-json' }

如何为有效的 json 初始化响应,我尝试了很多不同的方法。

关注 https://jestjs.io/docs/en/bypassing-module-mocks 的文章但我想返回并测试 json。

最佳答案

我们应该使用 jest.mock(moduleName, factory, options)模拟 node-fetch模块和 fetch功能。
为了构造fetch的响应对象功能,你需要使用Response node-fetch 提供的类模块,所以使用 jest.requireActual(moduleName)获得原始的,未模拟的 node-fetch模块和 Response类(class)。
当然,我们可以任意构造响应对象,但是Response的实例类真的很接近真实的 react 。headers 也是如此目的。
这是一个工作演示:index.js :

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

module.exports = {
  async doSomething(url, token) {
    return fetch(url).then(res => res.json());
  }
};
index.spec.js :
jest.mock('node-fetch');

const fetch = require('node-fetch');
const { Response, Headers } = jest.requireActual('node-fetch');
const mod = require('./');

const meta = {
  'Content-Type': 'application/json',
  Accept: '*/*',
  'Breaking-Bad': '<3'
};
const headers = new Headers(meta);
const copyOfHeaders = new Headers(headers);

const ResponseInit = {
  status: 200,
  statusText: 'fail',
  headers: headers
};

test('Basic Test', async () => {
  const token = '';
  const downloadDocumentData = { data: {} };
  const getDocList = new Response(JSON.stringify(downloadDocumentData), ResponseInit);
  fetch.mockResolvedValueOnce(Promise.resolve(getDocList));
  const res = await mod.doSomething('mock', token);
  expect(res).toEqual({ data: {} });
  expect(fetch).toBeCalledWith('mock');
});
单元测试结果:
 PASS  src/stackoverflow/58648691/index.spec.js
  ✓ Basic Test (5ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.557s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58648691

关于node.js - 用 Jest 方式模拟 Node 获取,创建一个用于模拟的响应对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58648691/

相关文章:

sql - 使用限制的 Sequelize 分页需要 4 倍的时间来加载。我该如何优化?

node.js - 使用 mongoose 与 Mongodb 聚合

javascript - API 返回数据,但在 undefined object 中。这是怎么回事?

c# - 在 Visual Studio 2010 中进行单元测试 (c#)。我做错了什么?测试总是失败

javascript - Jest 模拟 - 如何在测试之间恢复原始功能

node.js - 无法使用npm安装oracle包

java - 在测试期间清除嵌入式 activemq 数据

javascript - 如何在 Jest 中测试抛出异常的类型

node.js - jest.setTimeout.Error : Mocking Express middleware with Jest and Supertest

react-native - 部分模拟 `react-native` 模块