gpt4 book ai didi

angular - 从服务返回的 Observable 的单元测试值(使用异步管道)

转载 作者:搜寻专家 更新时间:2023-10-30 21:16:29 25 4
gpt4 key购买 nike

运行 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();
}
}
    <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>

还有我的 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));
});

具体来说,我想知道:

1) 我开始创建一个异步“it”测试,但当它不起作用时我感到很惊讶。为什么在我处理异步数据流时同步测试有效?

2) 当我检查 component.items 与 Observable.of(mockItems) 的等价性时,我是否真的在测试这些值是否相等?还是我只是在测试它们都是 Observable?有没有更好的办法?

最佳答案

Angular 提供了用于测试异步值的实用程序。您可以使用 async utility with the fixture.whenStable方法或 fakeAsync utility with the tick() function .然后使用 DebugElement,您实际上可以查询您的模板以确保正确加载值。

两种测试方法都有效。

async 实用程序与 whenStable 一起使用:

保持你的设置不变,你很高兴去那里。您需要添加一些代码来获取列表的调试元素。在您的 beforeEach 中:

const list = fixture.debugElement.query(By.css('list-group'));

然后您可以深入了解该列表并获取单个项目。我不会深入探讨如何使用 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');
*/
}
}));

fakeAsync 实用程序与 tick 结合使用:

it('should get the dashboard items when initialized', fakeAsync(() => {
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');
*/
}));

因此,总而言之,不要为了简化测试而从模板中删除 async 管道。 async 管道是一个很棒的实用程序,可以为您做很多清理工作,而且 Angular 团队为这个确切的用例提供了一些非常有用的测试实用程序。希望上述技术之一有效。听起来像是使用 DebugElement 并且上述实用程序之一会对您有很大帮助:)

关于angular - 从服务返回的 Observable 的单元测试值(使用异步管道),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48328292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com