[Angular] Testando Objetos Nativos do Navegador
Tato Petry
Posted on July 25, 2024
O Problema
Imagine que você está criando uma aplicação Angular e precisa redirecionar o usuário para um site externo, como o site da banda de grunge americana Pearl Jam. Uma forma comum de fazer isso é manipulando o objeto window. Por exemplo, podemos ter uma função que muda o window.location.href para redirecionar o usuário:
redirectToPearlJam() {
window.location.href = 'https://pearljam.com';
}
Agora, como a gente testa isso?
Testando a Função de Redirecionamento
Testar código que manipula o objeto window pode ser complicado, pois o window é uma API global do navegador. Mas calma, que tem solução! Aqui vão algumas dicas para fazer isso de uma forma tranquila.
1. Usando Jasmine Spy
A primeira solução é usar os spies do Jasmine para monitorar e interceptar chamadas ao window.location.href. Veja como fazer isso:
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { YourComponent } from './your-component';
describe('YourComponent', () => {
let component: YourComponent;
let fixture: ComponentFixture<YourComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [YourComponent]
}).compileComponents();
fixture = TestBed.createComponent(YourComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should redirect to Pearl Jam website', () => {
spyOn(window, 'open');
component.redirectToPearlJam();
expect(window.open).toHaveBeenCalledWith('https://pearljam.com');
});
});
2. Mocking Window Object
Outra forma é criar um mock do objeto window para usar nos testes. Podemos fazer isso injetando o window no componente:
export function windowFactory() {
return window;
}
@NgModule({
providers: [
{ provide: 'Window', useFactory: windowFactory }
]
})
export class AppModule { }
E no componente, vamos usar o objeto injetado:
import { Inject, Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class YourService {
constructor(@Inject('Window') private window: Window) {}
redirectToPearlJam() {
this.window.location.href = 'https://pearljam.com';
}
}
No teste, podemos criar um mock do window:
import { TestBed } from '@angular/core/testing';
import { YourService } from './your-service';
describe('YourService', () => {
let service: YourService;
let mockWindow: { location: { href: string } };
beforeEach(() => {
mockWindow = { location: { href: '' } };
TestBed.configureTestingModule({
providers: [
YourService,
{ provide: 'Window', useValue: mockWindow }
]
});
service = TestBed.inject(YourService);
});
it('should redirect to Pearl Jam website', () => {
service.redirectToPearlJam();
expect(mockWindow.location.href).toEqual('https://pearljam.com');
});
});
3. Atribuindo Mock à Variável do Componente
Outra abordagem é criar uma variável dentro do componente que guarda o objeto window. Nos testes, podemos atribuir um mock a essa variável. Aqui está como fazer isso:
No componente, adicione uma variável para o window:
export class YourComponent {
private window: Window;
constructor() {
this.window = window;
}
redirectToPearlJam() {
this.window.location.href = 'https://pearljam.com';
}
}
No teste, substituímos a variável window do componente por um mock:
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { YourComponent } from './your-component';
describe('YourComponent', () => {
let component: YourComponent;
let fixture: ComponentFixture<YourComponent>;
let mockWindow: { location: { href: string } };
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [YourComponent]
}).compileComponents();
fixture = TestBed.createComponent(YourComponent);
component = fixture.componentInstance;
mockWindow = { location: { href: '' } };
component['window'] = mockWindow; // Atribuímos o mock aqui
fixture.detectChanges();
});
it('should redirect to Pearl Jam website', () => {
component.redirectToPearlJam();
expect(mockWindow.location.href).toEqual('https://pearljam.com');
});
});
Conclusão
Testar código que interage com o objeto window no Angular pode parecer complicado, mas com essas estratégias, fica bem mais fácil. Usar spies do Jasmine, criar um mock do window ou usar uma variável no componente para o objeto window são abordagens eficazes que vão te ajudar a manter seus testes limpos e funcionais.
Posted on July 25, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.