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

390
Views
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 answers
Answer question

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 Report

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 Report

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 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!