gpt4 book ai didi

unit-testing - 测试可观察对象 Angular 2 karma

转载 作者:太空狗 更新时间:2023-10-29 17:37:04 26 4
gpt4 key购买 nike

我正在使用 Karma 处理我的 Angular 2 单元测试用例,我遇到了一个函数,我在其中运行下面一行的测试

expect(component.subscribeToEvents()).toBeTruthy();

我查看了我的覆盖代码,测试文件中的行似乎没有覆盖订阅中的任何内容。我尝试使用 MockBackend 在服务函数内模拟 api 调用,但我不确定如何对订阅的对象进行模拟,有人可以帮我吗?

下面是test.component.ts

subscribeToEvents() {
this.subscription = this.czData.$selectedColorZone
.subscribe(items => {
this.resourceLoading = true;
if (!this.resourceData || (this.resourceData && this.resourceData.length === 0)) {
this.settings.layout.flypanel.display = false;
this.getAllResources(this.pagination.start, this.pagination.size);
}
else {
this.pagination.start = 1;
this.pagination.end = this.pagination.size;
this.getAllResources(1, this.pagination.size);
this.settings.layout.flypanel.display = true;
}
});
return true;

覆盖代码截图 enter image description here

最佳答案

您不能这样做,因为订阅是异步解决的。因此同步测试在异步任务解决之前完成。

如果你想要的只是覆盖,你可以让测试async。这将导致 Angular 测试区域在完成测试之前等待异步任务解决

import { async } from '@angular/core/testing';

it('..', async(() => {
component.subscribeToEvents();
}))

您不能在这里尝试任何期望,因为没有用于解决任务时的回调 Hook 。所以这真的是一个毫无意义的测试。它会给你覆盖,但你实际上并没有测试任何东西。例如,您可能想要测试在解析订阅时是否设置了变量。

根据提供的代码,我要做的只是模拟服务,并使其同步。你怎么能那样做?我们可以让模拟类似于

class CzDataSub {
items: any = [];

$selectedColorZone = {
subscribe: (callback: Function) => {
callback(this.items);
}
}
}

然后在测试中配置就可以了

let czData: CzDataStub;

beforeEach(() => {
czData = new CzDataStub();
TestBed.configureTestingModule({
providers: [
{ provide: CzData, useValue: czData }
]
})
})

现在在你的测试中,你不需要让它成为 async,你可以通过设置 mock 的 items 属性来提供你想要的任何值,订阅者会得到它

it('..', () => {
czData.items = something;
component.subscribeToEvents();
expect(component.settings.layout.flypanel.display).toBe(false);
})

更新

我想我写这篇文章的时候是半睡半醒的。上述说法之一是错误的

You can't try to expect anything here, as there is no callback hook for when the task is resolved.

这并不完全正确。这就是 fixture.whenStable() 的用途。例如,如果这是您的服务

class CzData {
_value = new Subject<>();

$selectedColorZone = this._value.asObservable();

setValue(value) {
this._value.next(value);
}
}

那么这就是你让测试工作的方式

let czData: CzData;
let fixture: ComponentFixture<YourComponent>;
let component: YourComponent;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [ CzData ],
declarations: [ YourComponent ]
});
fixture = TestBed.createComponent(YourComponent);
component = fixture.componentInstance;
czData = TestBed.get(czData);
})

it('..', async(() => {
component.subscribeToEvents();
czData.setValue(somevalue);
fixture.whenStable().then(() => {
expect(component.settings.layout.flypanel.display).toBe(false);
})
}))

我们使用 fixture.whenStable() 来等待异步任务完成。

这并不是说使用 mock 是错误的。很多时候,使用模拟是可行的方法。我只是想更正我的陈述,并展示如何做到这一点。

关于unit-testing - 测试可观察对象 Angular 2 karma ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41249743/

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