Jest 的 spyOn 期间出现类型错误:无法设置 #<Object> 的属性 getRequest它只有一个吸气剂 [英] TypeError during Jest's spyOn: Cannot set property getRequest of #<Object> which has only a getter
问题描述
我正在使用 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)
我用谷歌搜索了这个,只找到了关于热重载的帖子.那么在 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
产生这个:
'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
尝试用包裹原始属性的 spy 替换该属性函数,但如果属性仅用 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
所在的模块code> 被定义并使用该模块来创建间谍.
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 的建议模拟整个 utils/serverRequests
模块
Mock the entire utils/serverRequests
module as suggested by @Volodymyr and @TheF
这篇关于Jest 的 spyOn 期间出现类型错误:无法设置 #<Object> 的属性 getRequest它只有一个吸气剂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!