Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

430
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda