【问题标题】:How to insert the correct response data into Jest?如何将正确的响应数据插入 Jest?
【发布时间】:2021-02-24 11:17:30
【问题描述】:

基于excellent answers,我正在尝试在类似的功能上实现 JestJS。

问题

问题在于我如何在jest.mock() 中插入模拟响应数据。下面我描述并包含了我使用过的所有文件。

谁能弄清楚我做错了什么?

这是一个可以试用的实时版本。 https://repl.it/@SandraSchlichti/jest-playground-1#getStatusCode.js

背景

首先我通过

转储正确的响应数据
const getStatusCode = require('./getStatusCode');

getStatusCode({
  url: 'https://google.com',
  statusCode: 200,
  timeout: 1000,
  maxRedirects: 0
});

getStatusCode.js

const axios = require('axios');
const qs = require('qs');

module.exports = async (options) => {
  options              = options || {};
  options.url          = options.url || {};
  options.statusCode   = options.statusCode || 0;
  options.timeout      = options.timeout || 1000;
  options.maxRedirects = options.maxRedirects || 0;

  try {
    const response = await axios.get(options.url, {
      timeout: options.timeout,
      maxRedirects: options.maxRedirects,
      // make all http status codes a success
      validateStatus: function (status) {
        return true;
      }
  });

    console.log(response); // here just to get the response data for Jest

    return (response.status === options.statusCode) ? 1 : 0;
  } catch (error) {
    return -1;
  }
};

输出非常大:

{
  status: 301,
  statusText: 'Moved Permanently',
  headers: {
    location: 'https://www.google.com/',
    'content-type': 'text/html; charset=UTF-8',
    date: 'Thu, 12 Nov 2020 10:48:21 GMT',
    expires: 'Sat, 12 Dec 2020 10:48:21 GMT',
    'cache-control': 'public, max-age=2592000',
    server: 'gws',
    'content-length': '220',
    'x-xss-protection': '0',
    'x-frame-options': 'SAMEORIGIN',
    'alt-svc': 'h3-Q050=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
    connection: 'close'
  },
  config: {
...

由于我只对status 的值感兴趣,因此我只需将第一部分复制/粘贴到我的getStatusCode.test.js 文件的data 中。

getStatusCode.test.js

const axios = require('axios');
const getStatusCode = require('./getStatusCode');

// whenever Axios is called from getStatusCode() it won't make a network
// connection, but return the following instead
jest.mock("axios", () => {
  return {
    get: jest.fn().mockResolvedValue({
      data:
      {
        status: 301,
        statusText: 'Moved Permanently',
        headers: {
          location: 'https://www.google.com/',
          'content-type': 'text/html; charset=UTF-8',
          date: 'Thu, 12 Nov 2020 10:09:41 GMT',
          expires: 'Sat, 12 Dec 2020 10:09:41 GMT',
          'cache-control': 'public, max-age=2592000',
          server: 'gws',
          'content-length': '220',
          'x-xss-protection': '0',
          'x-frame-options': 'SAMEORIGIN',
          'alt-svc': 'h3-Q050=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
          connection: 'close'
        }
      }
    })
  };
});

describe("test getStatusCode ", () => {
  // pretend to get data from the network connection
  let response;
  beforeAll(async () => {
    response = await getStatusCode({
      url: 'https://google.com',
      statusCode: 200,
      timeout: 1000,
      maxRedirects: 0
    });
  });

  // compare returned data with expected
  it("fetches raw response but we are only interested in the statuscode", async () => {
    // ensure the mocked Axios function has been called
    expect(axios.get).toHaveBeenCalled();

    expect(response.status).toBeGreaterThan(0);
  });

});

运行npm run test 给了我

 FAIL  ./getStatusCode.test.js
  ● Console

    console.log
      {
        data: {
          status: 301,
          statusText: 'Moved Permanently',
          headers: {
            location: 'https://www.google.com/',
            'content-type': 'text/html; charset=UTF-8',
            date: 'Thu, 12 Nov 2020 10:09:41 GMT',
            expires: 'Sat, 12 Dec 2020 10:09:41 GMT',
            'cache-control': 'public, max-age=2592000',
            server: 'gws',
            'content-length': '220',
            'x-xss-protection': '0',
            'x-frame-options': 'SAMEORIGIN',
            'alt-svc': 'h3-Q050=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
            connection: 'close'
          }
        }
      }

以后

  ● test getStatusCode  › fetches raw response but we are only interested in the statuscode

    expect(received).toBeGreaterThan(expected)

    Matcher error: received value must be a number or bigint

    Received has value: undefined

很明显,我没有正确复制axios.get() 的回复。

我做错了什么?

【问题讨论】:

  • 由于您的实现会检查 response.statusoptions.statusCode,因此最好有两种情况 - 一种不匹配,另一种匹配

标签: javascript node.js ecmascript-6 jestjs


【解决方案1】:

您的函数 getStatusCode 检查响应并返回 -1 或 0。

所以你不能指望它有属性status

你可以检查一下是不是toBeGreaterThanOrEqual归零

expect(response).toBeGreaterThanOrEqual(0)

working example

编辑:如果你想断言模拟函数返回了一个用具有 data.status 的对象解析的承诺,你可以像这样使用 jest 模拟函数的mock property

expect(await axios.get.mock.results[0].value).toHaveProperty('data.status', 301)

// where axios.get.mock.results is an array with the result for each call
// and "[0].value" is the result for the first call
// which would be a reference to the promise object, hence the await

但通常你想测试你的实现,而不是模拟函数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-07
    • 2017-01-12
    • 2017-07-24
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    相关资源
    最近更新 更多