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 delservice = TestBed.get(MyService);
llamar. - Me burlaba
BreakpointObserver
con un spyObj, y llamó a una función falsa en lugar de laBreakpointObserver.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 elresize()
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 .