MutationObserver é um mecanismo útil para observar mudanças no DOM e responder a elas.
A interface MutationObserver fornece a capacidade de observar as alterações feitas na árvore DOM.
Aqui está um exemplo que observa uma mudança de classe temática.
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(); }
No entanto, se você esquecer de desconectar, poderá estar se expondo a vazamentos de memória, dependendo do que é acessado nas funções do MutationObserver.
Não seria ótimo ter um teste que pudesse validar que desconectamos nossos observadores?
Acontece que é possível validar que todo MutationObserver que está observando o DOM também está desconectado. (Você pode precisar de mais de um teste se precisar exercitar diferentes caminhos de código para configurar os MutationObservers)
A ideia é zombar do MutationObserver global com sub-simulações para seus métodos de observação e de desconexão. Antes do mock ser retornado, nós o gravamos em um array para que possamos validar todas as instâncias no final da execução do teste.
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(); } }); });
Desta forma podemos validar que cada MutationObserver, configurado durante o teste, também está desconectado no final do teste.
Stephen Cooper - Desenvolvedor Sênior na AG Grid
Siga-me no X @ScooperDev
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3