Jest的spyOn期间发生TypeError:无法设置#< Object>的属性getRequest;里面只有吸气剂 [英] TypeError during Jest's spyOn: Cannot set property getRequest of #<Object> which has only a getter

查看:96
本文介绍了Jest的spyOn期间发生TypeError:无法设置#< Object>的属性getRequest;里面只有吸气剂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用TypeScript编写React应用程序.我使用Jest进行单元测试.

I'm writing a React application with TypeScript. I do my unit tests using Jest.

我有一个可以进行API调用的函数:

I have a function that makes an API call:

import { ROUTE_INT_QUESTIONS } from "../../../config/constants/routes";
import { intQuestionSchema } from "../../../config/schemas/intQuestions";
import { getRequest } from "../../utils/serverRequests";

const intQuestionListSchema = [intQuestionSchema];

export const getIntQuestionList = () => getRequest(ROUTE_INT_QUESTIONS, intQuestionListSchema);

getRequest 函数如下所示:

import { Schema } from "normalizr";
import { camelizeAndNormalize } from "../../core";

export const getRequest = (fullUrlRoute: string, schema: Schema) =>
  fetch(fullUrlRoute).then(response =>
    response.json().then(json => {
      if (!response.ok) {
        return Promise.reject(json);
      }
      return Promise.resolve(camelizeAndNormalize(json, schema));
    })
  );

我想像这样使用Jest尝试API函数:

I wanted to try the API function using Jest like this:

import fetch from "jest-fetch-mock";
import { ROUTE_INT_QUESTIONS } from "../../../config/constants/routes";
import {
  normalizedIntQuestionListResponse as expected,
  rawIntQuestionListResponse as response
} from "../../../config/fixtures";
import { intQuestionSchema } from "../../../config/schemas/intQuestions";
import * as serverRequests from "./../../utils/serverRequests";
import { getIntQuestionList } from "./intQuestions";

const intQuestionListSchema = [intQuestionSchema];

describe("getIntQuestionList", () => {
  beforeEach(() => {
    fetch.resetMocks();
  });

  it("should get the int question list", () => {
    const getRequestMock = jest.spyOn(serverRequests, "getRequest");
    fetch.mockResponseOnce(JSON.stringify(response));

    expect.assertions(2);
    return getIntQuestionList().then(res => {
      expect(res).toEqual(expected);
      expect(getRequestMock).toHaveBeenCalledWith(ROUTE_INT_QUESTIONS, intQuestionListSchema);
    });
  });
});

问题是带有 spyOn 的行引发以下错误:

The problem is that the line with spyOn throws the following error:

  ● getRestaurantList › should get the restaurant list

    TypeError: Cannot set property getRequest of #<Object> which has only a getter

      17 |
      18 |   it("should get the restaurant list", () => {
    > 19 |     const getRequestMock = jest.spyOn(serverRequests, "getRequest");
         |                                 ^
      20 |     fetch.mockResponseOnce(JSON.stringify(response));
      21 |
      22 |     expect.assertions(2);

      at ModuleMockerClass.spyOn (node_modules/jest-mock/build/index.js:706:26)
      at Object.spyOn (src/services/api/IntQuestions/intQuestions.test.ts:19:33)

我在Google上搜索了此信息,但只找到了有关热重装的帖子.那么在Jest测试期间可能是什么原因造成的呢?我怎样才能通过这项考试?

I googled this and only found posts about hot reloading. So what could cause this during Jest test? How can I get this test to pass?

推荐答案

这个很有趣.

Babel 生成的属性只为重新导出的函数定义了 get .

Babel generates properties with only get defined for re-exported functions.

utils/serverRequests/index.ts 从其他模块重新导出功能,因此当使用 jest.spyOn 监视重新导出的功能时会引发错误

utils/serverRequests/index.ts re-exports functions from other modules so an error is thrown when jest.spyOn is used to spy on the re-exported functions.

鉴于此代码,重新导出了 lib 中的所有内容:

Given this code re-exporting everything from lib:

export * from './lib';

... Babel 产生以下内容:

...Babel produces this:

'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _lib = require('./lib');

Object.keys(_lib).forEach(function (key) {
  if (key === "default" || key === "__esModule") return;
  Object.defineProperty(exports, key, {
    enumerable: true,
    get: function get() {
      return _lib[key];
    }
  });
});

请注意,所有属性均仅通过 get 定义.

Note that the properties are all defined with only get.

在这些属性中的任何一个上尝试使用 jest.spyOn 都会产生您所看到的错误,因为 jest.spyOn 试图用间谍将原始属性包裹起来函数,但如果仅使用 get 定义属性,则无法执行.

Trying to use jest.spyOn on any of those properties will generate the error you are seeing because jest.spyOn tries to replace the property with a spy wrapping the original function but can't if the property is defined with only get.

不是将 ../../utils/serverRequests (将 getRequest 重新导出)导入测试中,而是将模块导入 getRequest 并使用该模块创建间谍.

Instead of importing ../../utils/serverRequests (which re-exports getRequest) into the test, import the module where getRequest is defined and use that module to create the spy.

按照@Volodymyr和@TheF

Mock the entire utils/serverRequests module as suggested by @Volodymyr and @TheF

这篇关于Jest的spyOn期间发生TypeError:无法设置#&lt; Object&gt;的属性getRequest;里面只有吸气剂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆