MutationObserver es un mecanismo útil para observar cambios en el DOM y responder a ellos.
La interfaz MutationObserver proporciona la capacidad de observar los cambios que se realizan en el árbol DOM.
Aquí hay un ejemplo que observa un cambio de clase de tema.
function setUpThemeClassObservers() { const observer = new MutationObserver(() => { const themeClass = this.getThemeClass(); this.fireStylesChangedEvent('themeChanged'); }); observer.observe(this.eGridDiv, { attributes: true, attributeFilter: ['class'], }); // we must disconnect otherwise "this" will not be GC'd // causing a memory leak return () => observer.disconnect(); }
Sin embargo, si olvida desconectarse, podría exponerse a pérdidas de memoria dependiendo de a qué se acceda desde las funciones de MutationObserver.
¿No sería fantástico tener una prueba que pueda validar que desconectamos a nuestros observadores?
Resulta que es posible validar que cada MutationObserver que está observando el DOM también esté desconectado. (Es posible que necesite más de una prueba si tiene que utilizar diferentes rutas de código para configurar MutationObservers)
La idea es burlarse del MutationObserver global con sub simulacros de sus métodos de observación y desconexión. Antes de devolver el simulacro, lo registramos en una matriz para que podamos validar todas las instancias al final de la ejecución de la prueba.
describe('Mutation Observers Disconnected', () => { let originalMutationObserver: typeof MutationObserver; const allMockedObservers: any = []; const mutationObserverMock = jest.fn().mockImplementation(() => { const mock = { observe: jest.fn(), disconnect: jest.fn(), takeRecords: jest.fn(), }; allMockedObservers.push(mock); return mock; }); beforeEach(() => { // Ensure we can restore the real MutationObserver after the test originalMutationObserver = global.MutationObserver; global.MutationObserver = mutationObserverMock; }); afterEach(() => { global.MutationObserver = originalMutationObserver; }); test('observer always disconnected after destroy', async () => { const api = createGrid(); // Perform some actions if required to exercise the code paths api.destroy(); expect(allMockedObservers.length).toBeGreaterThan(0); for (const mock of allMockedObservers) { expect(mock.observe).toHaveBeenCalled(); expect(mock.disconnect).toHaveBeenCalled(); } }); });
De esta manera podemos validar que cada MutationObserver, configurado durante la prueba, también se desconecte al final de la prueba.
Stephen Cooper - Desarrollador senior en AG Grid
Sígueme en X @ScooperDev
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3