게터밖에 없는 저는 TypeScript를 사용하여 React 어플리케이션을 작성하고 있습니다. 나는 제스트를 사용하여 단위 테스트를 한다.
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 테스트 중에 무엇이 이것을 야기할 수 있을까요? 이 시험을 통과하려면 어떻게 해야 하나요?
이번 건 재밌었어요.
쟁점.
Babel다음에서만 속성을 생성합니다. get정의되어 있습니다.
utils/serverRequests/index.ts다른 모듈로부터 기능을 재실행하여 에러가 발생하도록 합니다. jest.spyOn를 사용하여 재인식 기능을 감시합니다.
세부 사항
이 코드를 지정하면 모든 것을 재내보내고 있습니다. 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.
사용 시도 중 jest.spyOn이러한 속성 중 하나에 대해 표시되는 오류가 발생합니다. jest.spyOn속성을 원래 함수를 감싸는 스파이로 바꾸려고 하지만 속성이 다음과 같이만 정의되어 있으면 바꿀 수 없습니다. get.
솔루션
Import 대신 ../../utils/serverRequests(그것은 재작성됩니다). getRequest테스트에 모듈을 Import 합니다. getRequest이 모듈을 사용하여 스파이를 만듭니다.
대체 솔루션
전체를 조롱하다 utils/serverRequests@Volodymyr 및 @TheF에서 제안하는 모듈
코멘트에서 제시된 바와 같이, joke는 테스트 대상 오브젝트에 대해 es6 모듈오브젝트에 없는 세터를 필요로 합니다. jest.mock()를 사용하면 Import 후 필요한 모듈을 조롱함으로써 이 문제를 해결할 수 있습니다.
serverRequests 파일에서 내보내기를 비웃어 보십시오.
import * as serverRequests from './../../utils/serverRequests';
jest.mock('./../../utils/serverRequests', () => ({
getRequest: jest.fn()
}));
// ...
// ...
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);
});
});
다음은 유용한 링크입니다. https://jestjs.io/docs/en/es6-class-mocks https://jestjs.io/docs/en/mock-functions
테스트 대상 ts-jest컴파일러로서 다음과 같이 모듈을 조롱하면 동작합니다.
import * as serverRequests from "./../../utils/serverRequests";
jest.mock('./../../utils/serverRequests', () => ({
__esModule: true,
...jest.requireActual('./../../utils/serverRequests')
}));
const getRequestMock = jest.spyOn(serverRequests, "getRequest");
담당 의사의 농담: __esModule
최근에 우리가 사용하던 도서관에서 이런 일이 일어났어요. Babel은 라이브러리에서 내보낸 모든 멤버에게만 getter를 제공하고 있었기 때문에 테스트의 선두에서 이 작업을 수행했습니다.
jest.mock('some-library', () => ({
...jest.requireActual('some-library')
}));
이로 인해 라이브러리의 모든 속성에 대해 멤버가 포함된 일반 JS 개체가 새로 생성되었기 때문에 문제가 해결되었습니다.
이 문제가 있는 다른 사용자는 "느슨한" 변환을 사용하도록 babel을 설정하여 문제를 해결할 수 있습니다. .babelrc 파일로 설정하기만 하면 됩니다.
{
"presets": [
["@babel/preset-env", {
"loose": true
}]
]
}
Import를 변경하지 않고 그대로 두려면 다음과 같이 문제를 해결할 수 있습니다.
import * as lib from './lib'
jest.mock('./lib/subModule')
it('can be mocked', () => {
jest.spyOn(lib, 'subModuleFunction')
})
넣어야 jest.mock감시하고 싶은 추가 재실행 기능에 대한 회선을 표시합니다.
Jest Unit-Test에서의 업그레이드는 다음 항목을 통과할 때 실패합니다.
export * from './serverRequests';
파일을 직접 참조하여 "...getter" 문제만 발생하지 않도록 하십시오.
언급 URL : https://stackoverflow.com/questions/53162001/typeerror-during-jests-spyon-cannot-set-property-getrequest-of-object-which