Saltar al contenido

Cómo simular window.screen.width en prueba de unidad angular con Jasmine

Te doy la bienvenida a nuestro sitio, aquí encontrarás la solucíon de lo que estás buscando.

Solución:

Material angular burlón BreakpointObserver

Supongo que realmente no quieres burlarte de window.screen, en realidad quieres burlarte de BreakpointObserver. Después de todo, no es necesario probar su código, solo desea probar que su código responde correctamente al observable devuelto por BreakpointObserver.observe() con diferentes tamaños de pantalla.

Hay muchas formas diferentes de hacer esto. Para ilustrar un método, armé un STACKBLITZ con su código que muestra cómo abordaría esto. Cosas a tener en cuenta que difieren del código anterior:

  • Tu código configura los observables en el constructor. Debido a esto, el simulacro debe cambiarse ANTES de que se cree una instancia del servicio, por lo que verá la llamada a resize() sucede antes del service = TestBed.get(MyService); llamar.
  • Me burlaba BreakpointObserver con un spyObj, y llamó a una función falsa en lugar de la BreakpointObserver.observe() método. Esta función falsa usa un filtro que había configurado con los resultados que quería de las distintas coincidencias. Todos empezaron como false, porque los valores cambiarían dependiendo del tamaño de pantalla que se desee simular, y eso lo configura el resize() función que estaba usando en el código anterior.

Nota: ciertamente hay otras formas de abordar esto. Echa un vistazo al propio material angular breakpoints-observer.spec.ts en github. Este es un enfoque general mucho más agradable que el que describo aquí, que fue solo para probar la función que proporcionó.

Aquí hay un recorte del StackBlitz del nuevo sugerido describe función:

describe(MyService.name, () => 
  let service: MyService;
  const matchObj = [
    // initially all are false
     matchStr: '(min-width: 1024px)', result: false ,
     matchStr: '(min-width: 1366px)', result: false ,
     matchStr: '(max-width: 1366px)', result: false ,
  ];
  const fakeObserve = (s: string[]): Observable =>
    from(matchObj).pipe(
      filter(match => match.matchStr === s[0]),
      map(match => ( matches: match.result, breakpoints:  )),
    );
  const bpSpy = jasmine.createSpyObj('BreakpointObserver', ['observe']);
  bpSpy.observe.and.callFake(fakeObserve);
  beforeEach(() => 
    TestBed.configureTestingModule(
      imports: [],
      providers: [MyService,  provide: BreakpointObserver, useValue: bpSpy ],
    );
  );

  it('should be createable', () => 
    service = TestBed.inject(MyService);
    expect(service).toBeTruthy();
  );

  describe('observe()', () => 
    function resize(width: number): void 
      matchObj[0].result = width >= 1024;
      matchObj[1].result = width >= 1366;
      matchObj[2].result = width <= 1366;
    

    it('should return Observable', () => 
      resize(1000);
      service = TestBed.inject(MyService);
      service.observe().subscribe(mode => 
        expect(
          Object.values(SidebarMode).includes(SidebarMode[mode]),
        ).toBeTruthy();
      );
    );

    it('should return SidebarMode.Closed', () => 
      resize(600);
      service = TestBed.inject(MyService);
      service
        .observe()
        .subscribe(mode => expect(mode).toBe(SidebarMode.Closed));
    );

    it('should return SidebarMode.Minified', () => 
      resize(1200);
      service = TestBed.inject(MyService);
      service
        .observe()
        .subscribe(mode => expect(mode).toBe(SidebarMode.Minified));
    );

    it('should return SidebarMode.Open', () => 
      resize(2000);
      service = TestBed.inject(MyService);
      service.observe().subscribe(mode => expect(mode).toBe(SidebarMode.Open));
    );
  );
);

Supongo que BreakPointObserver escucha el evento de cambio de tamaño, así que tal vez podrías probar algo como burlarse de window.innerWidth / window.outerWidth con jazmín.

spyOnProperty(window, 'innerWidth').and.returnValue(760);

Luego, activa manualmente un evento de cambio de tamaño:

window.dispatchEvent(new Event('resize'));

Se vería así:

    it('should mock window inner width', () => 
        spyOnProperty(window, 'innerWidth').and.returnValue(760);
        window.dispatchEvent(new Event('resize'));
    );

Recuerda algo, que puedes optar por la opción de decir .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *