Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

418
Views
TypeError durante el spyOn de Jest: no se puede establecer la propiedad getRequest de #<Object> que solo tiene un getter

Estoy escribiendo una aplicación React con TypeScript. Hago mis pruebas unitarias usando Jest.

Tengo una función que hace una llamada a la 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);

La función getRequest se ve así:

 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)); }) );

Quería probar la función API usando Jest así:

 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); }); }); });

El problema es que la linea con spyOn arroja el siguiente 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)

Busqué en Google esto y solo encontré publicaciones sobre recarga en caliente. Entonces, ¿qué podría causar esto durante la prueba Jest? ¿Cómo puedo hacer para pasar esta prueba?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Este fue interesante.

Tema

Babel genera propiedades con solo definirse get funciones reexportadas.

utils/serverRequests/index.ts reexporta funciones de otros módulos, por lo que se genera un error cuando se usa jest.spyOn para espiar las funciones reexportadas.


Detalles

Dado este código reexportando todo desde lib :

 export * from './lib';

... Babel produce esto:

 '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]; } }); });

Tenga en cuenta que todas las propiedades están definidas solo con get .

Intentar usar jest.spyOn en cualquiera de esas propiedades generará el error que está viendo porque jest.spyOn intenta reemplazar la propiedad con un espía que envuelve la función original, pero no puede si la propiedad se define solo con get .


Solución

En lugar de importar ../../utils/serverRequests (que vuelve a exportar getRequest ) a la prueba, importe el módulo donde se define getRequest y use ese módulo para crear el espía.

Solución alternativa

Simule todo el módulo utils/serverRequests como lo sugieren @Volodymyr y @TheF

over 4 years ago · Santiago Trujillo Report

0

Como se sugiere en los comentarios, jest requiere un setter en el objeto probado que los objetos del módulo es6 no tienen. jest.mock() le permite resolver esto burlándose de su módulo requerido después de la importación.

Intente burlarse de las exportaciones de su archivo 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); }); });

Aquí hay algunos enlaces útiles:
https://jestjs.io/docs/en/es6-class-mocks
https://jestjs.io/docs/en/mock-functions

over 4 years ago · Santiago Trujillo Report

0

Probado con ts-jest como compilador, funcionará si se burla del módulo de esta manera:

 import * as serverRequests from "./../../utils/serverRequests"; jest.mock('./../../utils/serverRequests', () => ({ __esModule: true, ...jest.requireActual('./../../utils/serverRequests') })); const getRequestMock = jest.spyOn(serverRequests, "getRequest");

Documento oficial de Jest para __esModule

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!