Jest的spyOn期间发生TypeError:无法设置#< 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)
我在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 定义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
Mock the entire utils/serverRequests
module as suggested by @Volodymyr and @TheF
这篇关于Jest的spyOn期间发生TypeError:无法设置#< Object>的属性getRequest;里面只有吸气剂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!