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

389
Vistas
Broma: cómo burlarse de un método específico de una clase

Supongamos que tengo la siguiente clase:

 export default class Person { constructor(first, last) { this.first = first; this.last = last; } sayMyName() { console.log(this.first + " " + this.last); } bla() { return "bla"; } }

Supongamos que quiero crear una clase simulada donde el método 'sayMyName' se simulará y el método 'bla' permanecerá como está.

La prueba que escribí es:

 const Person = require("../Person"); jest.mock('../Person', () => { return jest.fn().mockImplementation(() => { return {sayMyName: () => { return 'Hello' }}; }); }); let person = new Person(); test('MyTest', () => { expect(person.sayMyName()).toBe("Hello"); expect(person.bla()).toBe("bla"); })

La primera declaración 'esperar' pasa, lo que significa que 'sayMyName' se burló con éxito. Pero, el segundo 'esperar' falla con el error:

TypeError: person.bla no es una función

Entiendo que la clase simulada borró todos los métodos. Quiero saber cómo simular una clase de modo que solo se simularán métodos específicos.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Usar jest.spyOn() es la forma adecuada de Jest de burlarse de un solo método y dejar el resto en paz. En realidad, hay dos enfoques ligeramente diferentes para esto.

1. Modificar el método solo en un solo objeto

 import Person from "./Person"; test('Modify only instance', () => { let person = new Person('Lorem', 'Ipsum'); let spy = jest.spyOn(person, 'sayMyName').mockImplementation(() => 'Hello'); expect(person.sayMyName()).toBe("Hello"); expect(person.bla()).toBe("bla"); // unnecessary in this case, putting it here just to illustrate how to "unmock" a method spy.mockRestore(); });

2. Modifique la clase en sí, para que todas las instancias se vean afectadas.

 import Person from "./Person"; beforeAll(() => { jest.spyOn(Person.prototype, 'sayMyName').mockImplementation(() => 'Hello'); }); afterAll(() => { jest.restoreAllMocks(); }); test('Modify class', () => { let person = new Person('Lorem', 'Ipsum'); expect(person.sayMyName()).toBe("Hello"); expect(person.bla()).toBe("bla"); });

Y en aras de la exhaustividad, así es como te burlarías de un método estático:

 jest.spyOn(Person, 'myStaticMethod').mockImplementation(() => 'blah');
over 4 years ago · Santiago Trujillo Denunciar

0

Editar 03/05/2021

Veo que varias personas no están de acuerdo con el siguiente enfoque, y eso es genial. Sin embargo, tengo un ligero desacuerdo con el enfoque de @blade, ya que en realidad no prueba la clase porque está usando mockImplementation . Si la clase cambia, las pruebas siempre pasarán dando falsos positivos. Así que aquí hay un ejemplo con spyOn .

 // person.js export default class Person { constructor(first, last) { this.first = first; this.last = last; } sayMyName() { return this.first + " " + this.last; // Adjusted to return a value } bla() { return "bla"; } }

y la prueba:

 import Person from './' describe('Person class', () => { const person = new Person('Guy', 'Smiley') // Spying on the actual methods of the Person class jest.spyOn(person, 'sayMyName') jest.spyOn(person, 'bla') it('should return out the first and last name', () => { expect(person.sayMyName()).toEqual('Guy Smiley') // deterministic expect(person.sayMyName).toHaveBeenCalledTimes(1) }); it('should return bla when blah is called', () => { expect(person.bla()).toEqual('bla') expect(person.bla).toHaveBeenCalledTimes(1) }) });

¡Salud! 🍻


No veo cómo la implementación simulada realmente resuelve algo para usted. Creo que esto tiene un poco más de sentido.

 import Person from "./Person"; describe("Person", () => { it("should...", () => { const sayMyName = Person.prototype.sayMyName = jest.fn(); const person = new Person('guy', 'smiley'); const expected = { first: 'guy', last: 'smiley' } person.sayMyName(); expect(sayMyName).toHaveBeenCalledTimes(1); expect(person).toEqual(expected); }); });
over 4 years ago · Santiago Trujillo Denunciar

0

He estado haciendo una pregunta similar y creo que encontré una solución. Esto debería funcionar sin importar dónde se use realmente la instancia de la clase Person.

 const Person = require("../Person"); jest.mock("../Person", function () { const { default: mockRealPerson } = jest.requireActual('../Person'); mockRealPerson.prototype.sayMyName = function () { return "Hello"; } return mockRealPerson }); test('MyTest', () => { const person = new Person(); expect(person.sayMyName()).toBe("Hello"); expect(person.bla()).toBe("bla"); });
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