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

249
Views
Jasmine: cómo probar funciones que solo deben llamarse una vez (ejecutadas a través de una variable de cierre)

Estoy usando un cierre para asegurarme de que algo solo se llame una vez:

 var pageDOM = (function() { var mounted = false return { initializePage: function() { if (mounted == false) { pageDOM.addBoxes(); mount = true } pageDOM.otherInitProcedures(); }, otherFunction: function() { } } })();

No estoy seguro de cuál es la forma correcta de pensar en las pruebas unitarias pageDOM.initializePage . Las especificaciones de Jasmine se ejecutan en orden aleatorio, y creo que es importante mantener esto para probar la integridad (es decir, NO me gustaría imponer un orden). Este es mi código de especificación:

 describe("pageDOM", function() { describe("initializePage", function() { beforeEach(function() { spyOn(pageDOM, "addBoxes") spyOn(pageDOM, "otherInitProcedures") }) describe("calling initializePage first time", function() { beforeEach(function() { pageDOM.initializePage(); }) it("should call both functions", function() { expect(pageDOM.otherInitProcedures).toHaveBeenCalled() expect(pageDOM.addBoxes).toHaveBeenCalled() }) describe("calling initializePage again", function() { beforeEach(function() { pageDOM.initializePage(); }) it("should only call otherInitProcedures", function() { expect(pageDOM.otherInitProcedures).toHaveBeenCalled() expect(pageDOM.addBoxes).not.toHaveBeenCalled() }) }) }) }) })

El problema es que si las especificaciones no se ejecutan en orden, ambas fallarán. ¿Cuál es una manera de probar esto, o debería incluso intentar probar esto?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Asignaría los espías a las variables y restablecería los espías en un gancho afterEach .

Algo como esto (sigue el !! en los comentarios):

 describe("pageDOM", function() { describe("initializePage", function() { // !! initialize these variables let addBoxesSpy; let otherInitProceduresSpy; beforeEach(function() { // !! assign the variables addBoxesSpy = spyOn(pageDOM, "addBoxes") otherInitProceduresSpy = spyOn(pageDOM, "otherInitProcedures") }) describe("calling initializePage first time", function() { beforeEach(function() { pageDOM.initializePage(); }) it("should call both functions", function() { expect(pageDOM.otherInitProcedures).toHaveBeenCalled() expect(pageDOM.addBoxes).toHaveBeenCalled() }) describe("calling initializePage again", function() { beforeEach(function() { pageDOM.initializePage(); }) it("should only call otherInitProcedures", function() { expect(pageDOM.otherInitProcedures).toHaveBeenCalled() expect(pageDOM.addBoxes).not.toHaveBeenCalled() }) }) }) // !! Reset the spies in an afterEach afterEach(() => { addBoxesSpy.calls.reset(); otherInitProceduresSpy.calls.reset(); }); }) })

Después de restablecer las llamadas a lo que está espiando, el orden ya no debería importar.

about 4 years ago · Juan Pablo Isaza Report

0

Entonces, su método "pageDOM" está lleno de estado, entonces, ¿por qué usar 2 veces describir y configurar la llamada al método "initializePage" cada vez al conectarlo beforeEach? No tiene sentido. En su lugar, puedes hacer esto:

 describe("pageDOM:initializePage", function() { describe("calling initializePage first time", function() { beforeEach(function() { spyOn(pageDOM, "addBoxes"); spyOn(pageDOM, "otherInitProcedures"); }) it("should call both functions", function() { pageDOM.initializePage(); expect(pageDOM.otherInitProcedures).toHaveBeenCalled() expect(pageDOM.addBoxes).toHaveBeenCalled() }) it("should only call otherInitProcedures", function() { pageDOM.initializePage(); expect(pageDOM.otherInitProcedures).toHaveBeenCalled() expect(pageDOM.addBoxes).not.toHaveBeenCalled() }) }) })

Jasmine ejecuta los bloques dentro de una descripción secuencialmente y también puede obtener los controles deseados. Enlace de stackblitz en funcionamiento para usted (ignore otros casos de prueba)

about 4 years ago · Juan Pablo Isaza Report

0

Para hacer que el código sea más comprobable, no iniciaría la función de inmediato.

 var pageDOMConstructor = vfunction() { var mounted = false return { initializePage: function() { if (mounted == false) { pageDOM.addBoxes(); mount = true } pageDOM.otherInitProcedures(); }, otherFunction: function() { } } }; var pageDOM = pageDOMConstructor();

entonces puedes probar pageDOMConstructor fácilmente. Para verificar con qué frecuencia se ha llamado a algo, puede usar toHaveBeenCalledTimes

esto no está del todo completo y puede necesitar algunos pequeños cambios, es solo para darle una idea de cómo resolver esto:

 describe("pageDOMConstructor", function () { describe("initializePage", function () { // setup variable, its a let because it will be reset before every test let pageDom; beforeEach(function () { pageDom = pageDOMConstructor(); spyOn(pageDOM, "addBoxes"); spyOn(pageDOM, "otherInitProcedures"); }); it("should call both functions when calling initializePage first time", function () { pageDOM.initializePage(); expect(pageDOM.otherInitProcedures).toHaveBeenCalledTimes(1); expect(pageDOM.addBoxes).toHaveBeenCalledTimes(1); }); it("should only call otherInitProcedures when calling initializePage again", function () { pageDOM.initializePage(); // you could remove these two lines because they are in the other test expect(pageDOM.otherInitProcedures).toHaveBeenCalledTimes(1); expect(pageDOM.addBoxes).toHaveBeenCalledTimes(1); pageDOM.initializePage(); expect(pageDOM.otherInitProcedures).toHaveBeenCalledTimes(1); expect(pageDOM.addBoxes).not.toHaveBeenCalledTimes(1); }); }); });

Cada it debe tratarse como una prueba separada, y deben ser completamente autosuficientes, con algunas excepciones como beforeEach

Cuando el código es difícil de probar, a menudo es una señal de que podría beneficiarse de refactorizarlo un poco. Descubrí que el código comprobable es igual a un código usable y flexible en producción.

about 4 years ago · Juan Pablo Isaza 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!