eri*_*rin 3 unit-testing jasmine typescript karma-runner angular
运行Angular / Jasmine / Karma,我有一个组件消耗服务来设置Observable'items'数组的值。我使用异步管道显示此内容。效果很好。
现在,我正在尝试建立一个单元测试并使其通过,但是我不确定我是否正确地验证了“ items”数组是否获得了正确的值。
这是相关的组件.html和.ts:
export class ViperDashboardComponent implements OnInit, OnDestroy {
items: Observable<DashboardItem[]>;
constructor(private dashboardService: ViperDashboardService) { }
ngOnInit() {
this.items = this.dashboardService.getDashboardItems();
}
}Run Code Online (Sandbox Code Playgroud)
<ul class="list-group">
<li class="list-group-item" *ngFor="let item of items | async">
<h3>{{item.value}}</h3>
<p>{{item.detail}}</p>
</li>
</ul>Run Code Online (Sandbox Code Playgroud)
而我的component.spec.ts:
beforeEach(() => {
fixture = TestBed.createComponent(ViperDashboardComponent);
component = fixture.componentInstance;
viperDashboardService =
fixture.debugElement.injector.get(ViperDashboardService);
mockItems = [
{ key: 'item1', value: 'item 1', detail: 'This is item 1' },
{ key: 'item2', value: 'item 2', detail: 'This is item 2' },
{ key: 'item3', value: 'item 3', detail: 'This is item 3' }
];
spy = spyOn(viperDashboardService, 'getDashboardItems')
.and.returnValue(Observable.of<DashboardItem[]>(mockItems));
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should call getDashboardItems after component initialzed', () => {
fixture.detectChanges();
expect(spy.calls.any()).toBe(true, 'getDashboardItems should be called');
});
it('should show the dashboard after component initialized', () => {
fixture.detectChanges();
expect(component.items).toEqual(Observable.of(mockItems));
});Run Code Online (Sandbox Code Playgroud)
具体来说,我想知道:
1)我开始创建一个异步的“ it”测试,但是当它不起作用时感到惊讶。在使用异步数据流时,为什么同步测试有效?
2)当我检查component.items与Observable.of(mockItems)的等效性时,我是否真的在测试这些值是否相等?还是我只是在测试它们都是可观察的?有没有更好的办法?
Angular提供了用于测试异步值的实用程序。您可以将async实用程序与fixture.whenStable方法一起使用,或者将fakeAsync实用程序与tick()函数一起使用。然后,使用DebugElement,您可以实际查询您的模板,以确保正确加载了这些值。
两种测试方法都可以使用。
通过以下方式使用async实用程序whenStable:
保持您的设置不变,您可以继续进行。您需要添加一些代码来获取列表的debug元素。在您的beforeEach:
const list = fixture.debugElement.query(By.css('list-group'));
Run Code Online (Sandbox Code Playgroud)
然后,您可以深入到该列表并获取单个项目。我不会太过深入地介绍如何使用,DebugElement因为这超出了此问题的范围。在此处了解更多信息:https : //angular.io/guide/testing#componentfixture-debugelement-and-querybycss。
然后在您的单元测试中:
it('should get the dashboard items when initialized', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => { // wait for your async data
fixture.detectChanges(); // refresh your fake template
/*
now here you can check the debug element for your list
and see that the items in that list correctly represent
your mock data
e.g. expect(listItem1Header.textContent).toEqual('list item 1');
*/
}
}));
Run Code Online (Sandbox Code Playgroud)
通过以下方式使用fakeAsync实用程序tick:
it('should get the dashboard items when initialized', async(() => {
fixture.detectChanges();
tick(); // wait for async data
fixture.detectChanges(); // refresh fake template
/*
now here you can check the debug element for your list
and see that the items in that list correctly represent
your mock data
e.g. expect(listItem1Header.textContent).toEqual('list item 1');
*/
}
}));
Run Code Online (Sandbox Code Playgroud)
因此,总而言之,请勿async仅从模板中删除管道以简化测试。该async管道是一个非常实用和做了很多清理你,加上角队已经提供了一些非常有用的测试UTILITES这个确切的用例。希望以上技术之一能奏效。听起来像是使用DebugElement,上述工具之一将为您提供很多帮助:)
| 归档时间: |
|
| 查看次数: |
6224 次 |
| 最近记录: |