Angular2 – 单元测试Observable错误“无法读取未定义的属性’su
发布时间:2020-12-17 17:39:59 所属栏目:安全 来源:网络整理
导读:我有一个服务函数,它返回Observable,我正在我的一个组件中使用该服务.我使用 here发布的技术为组件编写了一个单元测试.然而,奇怪的是我得到了“无法读取未定义的属性’订阅’”. 被测组件: @Component({ moduleId: module.id,templateUrl: 'signup.componen
我有一个服务函数,它返回Observable,我正在我的一个组件中使用该服务.我使用
here发布的技术为组件编写了一个单元测试.然而,奇怪的是我得到了“无法读取未定义的属性’订阅’”.
被测组件: @Component({ moduleId: module.id,templateUrl: 'signup.component.html' }) export class SignupComponent implements OnInit { signupForm: FormGroup; submitted = false; registered = false; constructor(public router: Router,private fb: FormBuilder,public authService: AuthService) { this.signupForm = this.fb.group({ 'firstName': ['',Validators.required],'lastName': ['','email': ['',Validators.compose([Validators.required])],'password': ['','confirmPassword': ['',Validators.required] }); } ngOnInit() { } signup(event: any) { event.preventDefault(); this.submitted = true; if (!this.signupForm.valid) return; this.authService.register(this.signupForm.value) .subscribe( (res: Response) => { if (res.ok) { this.registered = true; } },(error: any) => { this.registered = false; console.log (error.status + ': ' + error.message); }); } } AbstractMockObservableService import { Subscription } from 'rxjs/Subscription'; export abstract class AbstractMockObservableService { protected _subscription: Subscription; protected _fakeContent: any; protected _fakeError: any; set error(err: any) { this._fakeError = err; } set content(data: any) { this._fakeContent = data; } get subscription(): Subscription { return this._subscription; } subscribe(next: Function,error?: Function,complete?: Function): Subscription { this._subscription = new Subscription(); spyOn(this._subscription,'unsubscribe'); if (next && this._fakeContent && !this._fakeError) { next(this._fakeContent); } if (error && this._fakeError) { error(this._fakeError); } if (complete) { complete(); } return this._subscription; } } 最后是单元测试 import { ComponentFixture,TestBed,async,fakeAsync,tick } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { DebugElement,Component,NO_ERRORS_SCHEMA } from '@angular/core'; import { Location } from '@angular/common'; import { Router } from '@angular/router'; import { FormBuilder } from "@angular/forms"; import { SignupComponent } from './signup.component'; import { AuthService } from "../index"; import { AbstractMockObservableService } from './abstract-mock-observable-service' let validUser = { firstName: "Ahmad",lastName: "Qarshi",email: "qarshi@gmail.com" password: "ahmad#123",confirmPassword: "ahmad#123" } class RouterStub { navigate(url: string) { return url; } } class LocationStub { path(url?: string) { return '/security/login'; } } class AuthServiceStub extends AbstractMockObservableService { register(model: any) { return this; } } let authServiceStub: AuthServiceStub; let comp: SignupComponent; let fixture: ComponentFixture<SignupComponent>; let de: DebugElement; let el: HTMLElement; function updateForm(firstName: string,lastName: string,email: string password: string,confPassword: string) { comp.signupForm.controls['firstName'].setValue(firstName); comp.signupForm.controls['lastName'].setValue(lastName); comp.signupForm.controls['email'].setValue(email); comp.signupForm.controls['password'].setValue(password); comp.signupForm.controls['confirmPassword'].setValue(confPassword); } describe('SignupComponent',() => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [SignupComponent],schemas: [NO_ERRORS_SCHEMA] }); }); compileAndCreate(); tests(); }); function compileAndCreate() { beforeEach(async(() => { authServiceStub = new AuthServiceStub(); TestBed.configureTestingModule({ providers: [ { provide: Router,useClass: RouterStub },{ provide: Location,useClass: LocationStub },{ provide: AuthService,useValue: authServiceStub },FormBuilder ] }) .compileComponents().then(() => { fixture = TestBed.createComponent(SignupComponent); comp = fixture.componentInstance; }); })); } function tests() { it('should call register user on submit',fakeAsync(() => { comp.submitted = false; updateForm(validUser.firstName,validUser.lastName,validUser.email,validUser.username,validUser.password,validUser.confirmPassword,validUser.tin,validUser.userType); spyOn(authServiceStub,'register'); authServiceStub.content = { ok: true }; fixture.detectChanges(); tick(); fixture.detectChanges(); fixture.debugElement.query(By.css('input[type=submit]')).nativeElement.click(); expect(comp.submitted).toBeTruthy('request submitted'); expect(authServiceStub.register).toHaveBeenCalled(); expect(comp.registered).toBeTruthy('user registered'); })); } 解决方法
当您监视服务方法并期望被调用时,您应该在spyOn上添加.and.callThrough().
你的代码应该是这样的:spyOn(authServiceStub,’register’).and.callThrough(); 然后,期望有BeenCalled(). 看看:http://blog.danieleghidoli.it/2016/11/06/testing-angular-component-mock-services/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |