Угловое 2 тестирование с роутером
У меня есть компонент, и когда пользователь входит в него, маршруты к URL-адресу под названием /dashboard
Я действительно изо всех сил пытаюсь понять, почему я получаю следующую ошибку.
cannot read property 'args' of undefined
Я следовал официальным документам по тестированию с маршрутизатором, найденным здесь https://angular.io/docs/ts/latest/guide/testing.html, но, похоже, это не помогает. Половина моей проблемы в том, что я не совсем понимаю весь код в документе. Вот мой юнит тест для маршрута
beforeEach(async(()=>{
class AuthStub{
private loggedin: boolean = false;
login(){
return this.loggedin = true;
}
};
class RouterStub{
navigateByUrl(url:string){return url;}
}
TestBed.configureTestingModule({
declarations: [ HomePageContentComponent ],
providers:[
{provide: Auth, useClass:AuthStub},
{provide: Router, useClass: RouterStub}
]
})
.compileComponents()
}));
beforeEach(()=>{
fixture = TestBed.createComponent(HomePageContentComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css('.loginbtn'));
el = de.nativeElement;
fixture.detectChanges();
});
it('Should log in and navigate to dashboard', inject([Router],(router:Router)=>{
const spy = spyOn(router, 'navigateByUrl');
el.click();
const navArgs = spy.calls.first().args[0];
expect(navArgs).toBe('/dashboard');
}))
});
Поэтому мой вопрос в том, что делает эта строка кода...
const navArgs = spy.calls.first().args[0];
и как я могу исправить мою проблему?
Услуга добавлена
@Injectable()
export class Auth {
lock = new Auth0Lock('fakefakefakefakefake', 'fake.auth0.com', {
additionalSignUpFields: [{
name: "address",
placeholder: "enter your address"
}],
theme: {
primaryColor:"#b3b3b3",
},
languageDictionary: {
title: "FAKE"
}
});
userProfile: any;
constructor(private router: Router) {
this.userProfile = JSON.parse(localStorage.getItem('profile'));
this.lock.on("authenticated", (authResult) => {
localStorage.setItem('id_token', authResult.idToken);
this.lock.getProfile(authResult.idToken, (error, profile) => {
if (error) {
alert(error);
return;
}
profile.user_metadata = profile.user_metadata || {};
localStorage.setItem('profile', JSON.stringify(profile));
this.userProfile = profile;
});
this.router.navigate(['/dashboard']);
});
}
public login(){
this.lock.show();
};
public authenticated() {
return tokenNotExpired();
};
public logout() {
localStorage.removeItem('id_token');
localStorage.removeItem('profile');
this.router.navigate(['/logout']);
};
}
1 ответ
Допустим, у вас есть следующий компонент:
@Component({
selector: 'home-comp',
template: `<button (click)="login()" class="loginbtn">Login</button>
`
})
export class HomePageContentComponent {
constructor(private auth: Auth, private router: Router) { }
login() {
this.router.navigateByUrl(`/dashboard`);
}
}
В вашем тесте после замены реального Router
с издевательской версией:
{ provide: Router, useClass: RouterStub }
Внутри вас чехол:
it('Should log in and navigate to dashboard', inject([Router],(router:Router)=>{
router
будет экземпляр RouterStub
,
тогда вы шпионите за navigateByUrl
метод наблюдения, сколько раз это называлось
const spy = spyOn(router, 'navigateByUrl');
поэтому, когда вы нажимаете на .loginbtn
кнопка router.navigateByUrl
работает (см. выше компонент) и spy
incrementes calls
с некоторой информацией (например, что было названо аргументом)
Наконец в этой строке
const navArgs = spy.calls.first().args[0];
Ожидается, что ваш router.navigateByUrl
метод вызывается хотя бы один раз, после чего получает переданный аргумент от первого вызова.
Здесь работает Живой Пример
Возможно, вы ошиблись где-то и ваши router.navigateByUrl
не выполнен