This is login.component.ts
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { LoginUser } from './loginUser.model'
import { UserService } from './user.service';
import { LoaderService } from '../shared/loader.service';
import 'rxjs/add/operator/toPromise';
@Component({
templateUrl: './login.component.html'
})
export class LoginComponent implements OnInit {
errorMessage: string;
loginForm: FormGroup;
loginObj = new LoginUser();
constructor(private userService: UserService, private loaderService: LoaderService, private router: Router, fb: FormBuilder) {
this.loginForm = fb.group({
userName: [null, Validators.required],
password: [null, Validators.required]
})
console.log(this.loginForm);
}
test() : void{
console.log("This is a test");
}
login(loginObjValue: any): void {
if (loginObjValue.userName == null || loginObjValue.password == null) {
console.log('error');
} else {
this.loginObj.userName = loginObjValue.userName;
this.loginObj.password = loginObjValue.password;
this.loaderService.displayLoader(true);
this.userService.login(this.loginObj)
.then((res) => {
console.log("data", res);
console.log("$localStorage.currentUser", localStorage);
let link = ['customercare/customer-ticket'];
this.loaderService.displayLoader(false);
this.router.navigate(link);
})
.catch(error => this.handleError(error));
}
}
private handleError(error: any): Promise<any> {
this.loaderService.displayLoader(false);
if (error._body) {
this.errorMessage = JSON.parse(error._body).error_description;
}
console.log('An error occurred', error);
return Promise.reject(error.message || error);
}
ngOnInit(): void {
}
}
@Component({
templateUrl: './login.component.html'
})
export class LoginComponent implements OnInit {
errorMessage: string;
loginForm: FormGroup;
loginObj = new LoginUser();
constructor(private userService: UserService, private loaderService: LoaderService, private router: Router, fb: FormBuilder) {
this.loginForm = fb.group({
userName: [null, Validators.required],
password: [null, Validators.required]
})
console.log(this.loginForm);
}
login(loginObjValue: any): void {
if (loginObjValue.userName == null || loginObjValue.password == null) {
console.log('error');
} else {
this.loginObj.userName = loginObjValue.userName;
this.loginObj.password = loginObjValue.password;
this.loaderService.displayLoader(true);
this.userService.login(this.loginObj)
.then((res) => {
console.log("data", res);
console.log("$localStorage.currentUser", localStorage);
let link = ['customercare/customer-ticket'];
this.loaderService.displayLoader(false);
this.router.navigate(link);
})
.catch(error => this.handleError(error));
}
}
}
userservice.ts的部分代码。请参考此代码。部分代码 userservice.ts。请参考此代码。部分代码 userservice.ts。请参考此代码。部分代码 userservice.ts。请参考此代码。部分代码 userservice.ts。请参阅此代码。
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { LoginUser } from './loginUser.model'
import { UserService } from './user.service';
import { LoaderService } from '../shared/loader.service';
import 'rxjs/add/operator/toPromise';
@Component({
templateUrl: './login.component.html'
})
export class LoginComponent implements OnInit {
errorMessage: string;
loginForm: FormGroup;
loginObj = new LoginUser();
constructor(private userService: UserService, private loaderService: LoaderService, private router: Router, fb: FormBuilder) {
this.loginForm = fb.group({
userName: [null, Validators.required],
password: [null, Validators.required]
})
console.log(this.loginForm);
}
test() : void{
console.log("This is a test");
}
login(loginObjValue: any): void {
if (loginObjValue.userName == null || loginObjValue.password == null) {
console.log('error');
} else {
this.loginObj.userName = loginObjValue.userName;
this.loginObj.password = loginObjValue.password;
this.loaderService.displayLoader(true);
this.userService.login(this.loginObj)
.then((res) => {
console.log("data", res);
console.log("$localStorage.currentUser", localStorage);
let link = ['customercare/customer-ticket'];
this.loaderService.displayLoader(false);
this.router.navigate(link);
})
.catch(error => this.handleError(error));
}
}
private handleError(error: any): Promise<any> {
this.loaderService.displayLoader(false);
if (error._body) {
this.errorMessage = JSON.parse(error._body).error_description;
}
console.log('An error occurred', error);
return Promise.reject(error.message || error);
}
ngOnInit(): void {
}
}
我写的很远:我无法调用登录功能。请指导我。
@Injectable()
export class UserService {
private URL = "";
constructor(private http: Http) { }
login(loginObj: LoginUser) {
let body = 'userName=' + loginObj.userName + '&password=' + loginObj.password + '&grant_type=password';
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
return this.http.post(this.URL + '/token', body, { headers: headers })
.toPromise()
.then((res: Response) => {
let data = res.json();
if (data && data.access_token) {
localStorage.setItem('currentUser', JSON.stringify(data));
}
return data;
})
}
}
答案 0 :(得分:0)
所以我不确定错误是什么,但我看到的最重要的事情可能是在创建组件之前没有调用compileComponents。
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers: [
{ provide: UserService, useValue: UserService },
]
}).compileComponents();
}); <--- also looked to be missing
这只是我的建议,我不在机器附近测试你的方式是否可行,但我也会在每个之前获取一个对fixture的引用,并使用它来在测试中创建你的组件。和上面一样但是:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers: [
{ provide: UserService, useValue: UserService },
]
}).compileComponents();
});
beforeEach(async(() => {
// components are now compiled
fixture = TestBed.createComponent(LoginComponent);
});
主要在您已经创建了对它的引用之前。您尝试在测试中重新创建该引用,但您可以在beforeEach中分配它并使用它。
此外,你的测试并没有真正做任何我能看到触发任何事情的事情。如果这是您的目标,您可以验证它是否存在。
it('should call the login method when the component does something',
inject([UserService], ((userService: UserService) => {
spyOn(userService, 'login');
let component = fixture.componentInstance;
component.doSomething();
expect(userService.login).toHaveBeenCalled();
});
}));
由于您只测试函数被调用,因此实际上不需要在异步中包装任何内容。您不是在等待DOM中的响应或其他任何事情,只是在调用组件自己的login()方法时,确实验证了服务上的login()方法。如果有任何疑问,你可以投入一个无害的fixture.detectChanges(),但我相信,如果你在模板中改变某些东西,通常也会确保元素已经传播回来。
老实说,即使是那种纯粹的单元测试。您可以为UserService编写其他单元测试。如果你想验证LoginComponent的某些方面,我会编写测试断言,一旦LoginComponent登录就应该变异或者是什么(可能是DOM中的文本已经改变等)。或者,如果您只是测试业务逻辑,则可以拦截登录调用以返回true或false并验证doSomething()是否正确响应。