这是测试中的组件:
@Component({
moduleId: module.id,
selector: 'my-search',
templateUrl: 'search.component.html',
styleUrls: ['search.component.css'],
})
export class SearchComponent implements OnInit {
things: Observable<Thing[]>;
private searchTerms = new Subject<string>();
constructor(private searchService: SearchService) { }
ngOnInit() {
this.things = this.searchTerms
.debounceTime(300)
.distinctUntilChanged()
.switchMap((term: string) => term
? this.searchService.search(term)
: Observable.of<Thing[]>([]));
}
search(term: string) {
this.searchTerms.next(term);
}
}
这里是search.component.html:
<form (submit)="search()">
<input #searchBox (keyup)="search(searchBox.value)" />
<button type="submit">Search</button>
</form>
<div *ngIf="(things | async)?.length == 0; else searchResults">No things found.</div>
<ng-template #searchResults>
<div class="search-results">
<div *ngFor="let thing of things | async" class="search-result">
{{thing.id}}
</div>
</div>
</ng-template>
这是失败的测试:
it('should exhibit issue', fakeAsync(() => {
component.ngOnInit();
fixture.detectChanges();
component.search('123');
tick(300);
fixture.detectChanges();
component.things.subscribe((things) => {
// This fails. (I've tried various things, this is just the latest attempt.)
expect(dom.querySelectorAll('.search-results .search-result').length).toBe(1);
});
}));
Here's a plunk with what I've got so far.
无论我做什么,我都看不到DOM的变化。 fixture.detectChanges()
没有对DOM做任何事情。
如何测试Observables?
答案 0 :(得分:0)
这对我有用
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
fixture.detectChanges();
app.search('123');
tick(400);
fixture.detectChanges();
const searchNodes = fixture.debugElement.queryAll(By.css('.search-results .search-result')).map((item) => item.nativeElement);
expect(searchNodes.length).toBe(3);
答案 1 :(得分:0)
终于开始工作了。您可以查看the plunk (version 25),但这是精简解决方案:
it('now works!', async(() => {
// Initialize the component.
component.ngOnInit();
fixture.detectChanges();
// The Observable is now initialized and we can now subscribe.
component.things.subscribe((things) => {
// Now that we've got the data, look for changes.
fixture.detectChanges();
// The DOM/view should now be up to date.
expect(dom.querySelectorAll('.search-results .search-result').length).toBe(1);
});
// Initiate stuff happening.
component.search('123');
}));
亮点:
async
代替fakeAsync
。detectChanges
,以便更新视图。我要注意的一件事:subscribe
是在事件之前还是之后(示例中对search
的调用)似乎并不重要案件。我之前已经把它放在了预防措施之前,因为这是一个很热门的事情。 Observable可能会在subscribe
寄存器之前处理该事件;然后观察者会错过通知,回调永远不会发射,测试将无效。