angular 6 unittest,()的可观察是同步的

时间:2018-06-18 13:17:43

标签: angular jasmine rxjs karma-jasmine rxjs6

如果你想知道,

必须删除以前的问题,重新制定:

我已经设置了这个组件:

@Component({
  selector: 'app-async',
  templateUrl: './async.component.html',
  styleUrls: ['./async.component.scss']
})
export class AsyncComponent implements OnInit {

  title$: Observable<string>;
  constructor(private stringService: AsyncStringService) { }

  ngOnInit() {
    this.title$ = this.stringService.getString();
  }
}

AsyncStringService.getString就是这样:

getString(): Observable<string>

,该组件的模板是:

<h1 id="title">{{title$ | async}}</h1>

我想使用jasmines异步功能测试组件行为,但如果我不考虑任何异步延续,我的测试也会起作用:

describe('AsyncComponent', () => {
  let fixture: ComponentFixture<AsyncComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ AsyncComponent ],
      providers: [ AsyncStringService ]
    })
    .compileComponents().then(() =>
      fixture = TestBed.createComponent(AsyncComponent));

  }));

  it('should not have resolved observable immedeatly', () => {
    const spy = spyOn(fixture.debugElement.injector.get(AsyncStringService), 'getString')
      .and.returnValue(of( 'value 1'));
    fixture.detectChanges();
    expect(fixture.debugElement.query(By.css('#title')).nativeElement.innerText).toEqual('value 1');
  });

  it('should have all observables resolved in whenStable', async(() => {
    const spy = spyOn(fixture.debugElement.injector.get(AsyncStringService), 'getString')
      .and.returnValue(of( 'value 1'));
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      fixture.detectChanges();
      expect(fixture.debugElement.query(By.css('#title')).nativeElement.innerText).toEqual('value 1');
    });
  }));


  it('should have all observables resolved when ticking', fakeAsync(() => {
    const spy = spyOn(fixture.debugElement.injector.get(AsyncStringService), 'getString')
      .and.returnValue(of( 'value 1'));
    fixture.detectChanges();
    tick();

    expect(fixture.debugElement.query(By.css('#title')).nativeElement.innerText).toEqual('value 1');
  }));
});

所有三个测试都成功,我希望间谍返回一个未通过第一次测试的观察者,因为它不考虑异步性。

此外,如果我错误地使用这些功能(async / fakeAsync),任何提示都会受到赞赏!

编辑:

我尝试了(&#39;值1&#39;)。pipe(延迟(100)),这会导致所有测试失败。我假设这是以某种方式连接到async / fakeAsync流不能看到的异步管道?

编辑:

我让同步任务失败,而done()和async()通过从我的间谍返回timer(10).pipe(map(() => 'value 1'))来传递。

然而,假的异步测试表现得很奇怪:

如果我检查订阅者中的可观察值,即使我根本不调用tick(),它也会通过 - 所以没有时间过去,时间永远不会发出值。

并且调用tick(100),它应该使时间(10)发出,不会导致值落在订阅者之外的模板中。

 it('should have all observables resolved when ticking the appropriate amount of time', fakeAsync(() => {
    const spy = spyOn(fixture.debugElement.injector.get(AsyncStringService), 'getString')
      .and.returnValue(timer(10).pipe(map(() => 'value 1')));
    fixture.componentInstance.ngOnInit();
    fixture.componentInstance.title$.subscribe(value => expect(value).toEqual('value 1'));
    fixture.componentInstance.title$.subscribe(() => {
      fixture.detectChanges();
      expect(fixture.debugElement.query(By.css('#title')).nativeElement.innerText).toEqual('value 1');
    });
    tick(100); // this does nothing
    fixture.detectChanges();
    expect(fixture.debugElement.query(By.css('#title')).nativeElement.innerText).toEqual('value 1');
    discardPeriodicTasks();
  }));

1 个答案:

答案 0 :(得分:0)

通过将异步调度程序作为of()的第二个参数传递给我,使嘲笑的可观察对象变为异步状态:

import {async as _async} from 'rxjs/scheduler/async';

var stub$ = of(stub, _async);