为角度应用编写单元测试,登录机制在单一概念上工作,页面将重定向到外部URL并为登录成功设置cookie值(基于cookie设置本地存储)。
在测试该场景浏览器重定向到外部页面并停止单元测试执行时。目前,在进行单元测试时,注释了重定向并测试了剩余的测试用例。
在重新部署到live时,我必须取消注释重定向代码。
如何在茉莉花中处理这种情况?
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private location: Location
) { }
canActivate(): boolean {
if (!localStorage.getItem('API_TOKEN')) {
this.redirectTOLogin();
return false;
} else {
return true;
}
}
redirectTOLogin() {
window.location.href = environment.appLoginUrl + environment.appUrl;
}
}
spec.ts
describe('Logged in guard should', () => {
let loggedInGuard: AuthGuard;
const router = {
navigate: jasmine.createSpy('navigate')
};
// async beforeEach
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule, CommonModule],
providers: [AuthGuard, Location, { provide: LocationStrategy, useClass: PathLocationStrategy },
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: Router, useValue: router }
]
})
.compileComponents(); // compile template and css
}));
// synchronous beforeEach
beforeEach(() => {
loggedInGuard = TestBed.get(AuthGuard);
});
it('be able to hit route when user is logged in', () => {
localStorage.setItem('API_TOKEN', 'fgsdhfhg4359854dsfsdf#@dfg4545nvnsjfjkh');
expect(loggedInGuard.canActivate()).toBe(true);
});
it('not be able to hit route when user is not logged in', () => {
localStorage.removeItem('API_TOKEN');
spyOn(loggedInGuard, 'redirectTOLogin');
expect(loggedInGuard.redirectTOLogin).toHaveBeenCalled();
});
});
答案 0 :(得分:3)
我建议将窗口调用外包到一个单独的函数中,然后在测试中创建一个间谍来检查它是否已被调用!
在这种情况下,您要测试的只是如果重定向被触发,而不是本机浏览器功能实际正在运行!
间谍茉莉创造然后l防止在测试中实际执行该功能!
redirect() {
window.location.href = 'logindomainname.com?ReturnUrl=http://localhost:4200';
}
// in your test then...
spyOn(component, 'redirect');
//...
expect(component.redirect). toHaveBeenCalled();
编辑:
在你的第一个测试用例中,我没有看到问题,这应该是有效的,它不应该重定向,因为逻辑不是这样的。
在你的第二个测试用例中,它应该失败,因为你根本没有调用canActivate
。所以以下内容应该会成功:
it('not be able to hit route when user is not logged in', () => {
localStorage.removeItem('API_TOKEN');
spyOn(loggedInGuard, 'redirectTOLogin');
expect(loggedInGuard.canActivate()).toBe(false);
expect(loggedInGuard.redirectTOLogin).toHaveBeenCalled();
});
这将调用canActivate
,它应返回false并在返回false之前调用redirectTOLogin
函数,然后由间谍识别。