【发布时间】:2019-04-09 06:16:53
【问题描述】:
我正在用 TypeScript 编写一个 React 应用程序。我使用 Jest 进行单元测试。
我有一个调用 API 的函数:
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 功能:
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的行抛出如下错误:
● 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 测试期间可能导致这种情况的原因是什么?我怎样才能让这个测试通过?
【问题讨论】:
-
你需要在没有setter的es6模块对象上使用
jest.mock() -
@Volodymyr 你能解释一下你会怎么做吗?我真的不明白。我从来没有遇到过 getter 和 setter 的话题。在 React Native 上,这个测试也为我通过了。只有在常规 React 上才会失败。
-
很奇怪。错误发生在 this line 上,其中 jest 尝试替换
serverRequests模块对象上的属性getRequest。我无法重现问题。serverRequests模块是否在其他地方被修改(可能是全局模拟的)?出于某种原因,getRequest最终成为导入模块对象的 getter 属性,从而防止它被间谍替换。 -
@brian-lives-outdoors 在
serverRequests/中有一个index.ts可以导入所有请求并再次导出它们,这样我就可以执行import { getRequest } from "../../utils/serverRequests";。会不会是这个原因?
标签: reactjs unit-testing jestjs spy spyon