es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

No se pueden leer las propiedades de null (leyendo ‘parentElement’) durante la prueba unitaria.

Estoy tratando de escribir una prueba unitaria para la siguiente función:

focusSkipButton(event: MouseEvent, isLoggedIn: boolean): void {
    if (isLoggedIn) {
        return;
    }
    const button: HTMLButtonElement = document.querySelector('.skip-btn');
    const overlay = document.querySelector('.story-viewer-login-container');
    const target = event.target as Element;
    if (event.target !== overlay &&
        (target.parentElement && target.parentElement !== overlay)) {
            button.focus();
    }
}

Esto es lo que he creado:

it('should set focus on skip button', fakeAsync(() => {
    let button = document.createElement('button');
    spyOn(document, 'querySelector').and.returnValue(button);
    spyOn(button, 'focus');
    let event = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true
    });
    let parent = document.createElement('div');
    let child = document.createElement('div');
    parent.append(child);
    child.dispatchEvent(event);
    component.focusSkipButton(event, false);
    tick();
    expect(button.focus).toHaveBeenCalled();
    component.focusSkipButton(event, true);
    tick();
    expect(button.focus).not.toHaveBeenCalled();
}));

Sin embargo, al ejecutar esta prueba, estoy obteniendo el siguiente error:

Cannot read properties of null (reading 'parentElement')

No estoy seguro de qué estoy pasando por alto aquí.
Cualquier ayuda sería muy apreciada.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el error se produce porque el objetivo del evento no tiene un elemento padre, que es lo que verifica el código. Para solucionar esto, puedes agregar una comprobación antes de acceder a la propiedad parentElement para asegurarte de que no sea nulo. Aquí está el código actualizado:

    it('should set focus on skip button', fakeAsync(() => {
      let button = document.createElement('button');
      spyOn(document, 'querySelector').and.returnValue(button);
      spyOn(button, 'focus');
    
      var event = new MouseEvent('click', {
        view: window,
        bubbles: true,
        cancelable: true
      });
    
      let parent = document.createElement('div');
      let child = document.createElement('div');
      parent.append(child);
      child.dispatchEvent(event);
    
      component.focusSkipButton(event, false);
      tick();
    
      expect(button.focus).toHaveBeenCalled();
    
      // add null check for parentElement
      let target = document.createElement('div');
      component.focusSkipButton({
        target: target,
        currentTarget: target
      }, false);
      tick();
    
      expect(button.focus).toHaveBeenCalled();
    
      component.focusSkipButton(event, true);
      tick();
    
      expect(button.focus).not.toHaveBeenCalled();
    }));
    

    Además de la corrección del error, he agregado otro caso de prueba para asegurarme de que el método también funcione cuando el objetivo del evento no tiene un parentElement. Esto se logra creando un nuevo elemento div y pasándolo directamente como el objetivo del evento, sin agregarlo a ningún elemento padre.

    ¡Espero que esto te ayude!

Comments are closed.