测试通过管道传输并使用异步管道的 Observable
Test Observable that is piped and uses async pipe
我有以下情况。我有一个 Observable,myObservable$
在 ngOnInit
中初始化。当发生这种情况时,observable 会被利用以复制最后一个值用于其他目的。除此之外,observable 使用 async
管道绑定到我的 html 上。如何使用 jasmine karma 测试我的点击功能是否正确发生?
html:
<input [ngModel]="myObservable$ |async">
ts:
ngOnInit():void {
this.myObservable$ = this.service.getThings()
.pipe(tap(value=>this.otherProperty=value))
}
我想测试一下,在这个例子中,this.otherProperty
是否真的有这个值。我该如何测试?
您应该将间谍安装到 this.service.getThings()
方法和 returns 一个其值立即可用的同步可观察对象上。然后,您可以在组件的 ngOnInit
方法上订阅它。最后,对 otherProperty
进行断言以检查该值。有关详细信息,请参阅 Component with async service
例如使用 angular
v11+
example.component.ts
:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ExampleService } from './example.service';
@Component({
selector: 'app-example',
template: '<input [ngModel]="myObservable$ |async">',
})
export class ExampleComponent implements OnInit {
myObservable$: Observable<string>;
otherProperty: string;
constructor(private service: ExampleService) {}
ngOnInit() {
this.myObservable$ = this.service
.getThings()
.pipe(tap((value) => (this.otherProperty = value)));
}
}
example.service.ts
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
@Injectable()
export class ExampleService {
constructor() {}
getThings() {
return of('your real implementation');
}
}
example.component.spec.ts
:
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { of } from 'rxjs';
import { ExampleComponent } from './example.component';
import { ExampleService } from './example.service';
fdescribe('65479995', () => {
let fixture: ComponentFixture<ExampleComponent>;
let component: ExampleComponent;
let exampleServiceSpy: jasmine.SpyObj<ExampleService>;
beforeEach(
waitForAsync(() => {
exampleServiceSpy = jasmine.createSpyObj('ExampleService', ['getThings']);
exampleServiceSpy.getThings.and.returnValue(of('fake implementation'));
TestBed.configureTestingModule({
declarations: [ExampleComponent],
imports: [FormsModule],
providers: [{ provide: ExampleService, useValue: exampleServiceSpy }],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(ExampleComponent);
component = fixture.componentInstance;
});
})
);
it('should pass', () => {
expect(component.otherProperty).toBeUndefined();
fixture.detectChanges();
expect(component.otherProperty).toBe('fake implementation');
expect(exampleServiceSpy.getThings).toHaveBeenCalled();
});
});
测试结果:
================================================================================
✔ Browser application bundle generation complete.
✔ Browser application bundle generation complete.
Chrome Headless 80.0.3987.87 (Mac OS 10.13.6): Executed 2 of 47 (skipped 45) SUCCESS (0.17 secs / 0.063 secs)
TOTAL: 2 SUCCESS
我有以下情况。我有一个 Observable,myObservable$
在 ngOnInit
中初始化。当发生这种情况时,observable 会被利用以复制最后一个值用于其他目的。除此之外,observable 使用 async
管道绑定到我的 html 上。如何使用 jasmine karma 测试我的点击功能是否正确发生?
html:
<input [ngModel]="myObservable$ |async">
ts:
ngOnInit():void {
this.myObservable$ = this.service.getThings()
.pipe(tap(value=>this.otherProperty=value))
}
我想测试一下,在这个例子中,this.otherProperty
是否真的有这个值。我该如何测试?
您应该将间谍安装到 this.service.getThings()
方法和 returns 一个其值立即可用的同步可观察对象上。然后,您可以在组件的 ngOnInit
方法上订阅它。最后,对 otherProperty
进行断言以检查该值。有关详细信息,请参阅 Component with async service
例如使用 angular
v11+
example.component.ts
:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ExampleService } from './example.service';
@Component({
selector: 'app-example',
template: '<input [ngModel]="myObservable$ |async">',
})
export class ExampleComponent implements OnInit {
myObservable$: Observable<string>;
otherProperty: string;
constructor(private service: ExampleService) {}
ngOnInit() {
this.myObservable$ = this.service
.getThings()
.pipe(tap((value) => (this.otherProperty = value)));
}
}
example.service.ts
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
@Injectable()
export class ExampleService {
constructor() {}
getThings() {
return of('your real implementation');
}
}
example.component.spec.ts
:
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { of } from 'rxjs';
import { ExampleComponent } from './example.component';
import { ExampleService } from './example.service';
fdescribe('65479995', () => {
let fixture: ComponentFixture<ExampleComponent>;
let component: ExampleComponent;
let exampleServiceSpy: jasmine.SpyObj<ExampleService>;
beforeEach(
waitForAsync(() => {
exampleServiceSpy = jasmine.createSpyObj('ExampleService', ['getThings']);
exampleServiceSpy.getThings.and.returnValue(of('fake implementation'));
TestBed.configureTestingModule({
declarations: [ExampleComponent],
imports: [FormsModule],
providers: [{ provide: ExampleService, useValue: exampleServiceSpy }],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(ExampleComponent);
component = fixture.componentInstance;
});
})
);
it('should pass', () => {
expect(component.otherProperty).toBeUndefined();
fixture.detectChanges();
expect(component.otherProperty).toBe('fake implementation');
expect(exampleServiceSpy.getThings).toHaveBeenCalled();
});
});
测试结果:
================================================================================
✔ Browser application bundle generation complete.
✔ Browser application bundle generation complete.
Chrome Headless 80.0.3987.87 (Mac OS 10.13.6): Executed 2 of 47 (skipped 45) SUCCESS (0.17 secs / 0.063 secs)
TOTAL: 2 SUCCESS