gpt4 book ai didi

javascript - Jasmine:用事件测试 observables

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

我正在尝试测试 angular2 应用程序。我有一个登录表单,它使用 observable 将数据发送到后端:

doLogin() {
this.usersService.login(this.model)
.subscribe((data) => {
console.log("In observable: " + data.isSuccess);
if (!data.isSuccess) {
this.alerts.push({});
}
});
}

在测试中,我在服务函数上添加了一个 spy ,它返回可观察的,以便该组件可以在它上面工作:

 usersService.login.and.returnValue(Observable.of(
<LoginResponse>{
isSuccess: true
}));

当一切准备就绪后,我在提交按钮上发送一个事件,它触发组件中的 doLogin 函数:

submitButton.dispatchEvent(new Event("click"));
fixture.detectChanges();

它工作正常。不幸的是,当我检查是否在测试中调用了 usersService.login 时:

expect(usersService.login).toHaveBeenCalled();

我得到一个错误,因为 observable 没有完成并且登录还没有被调用。

我应该如何确保在 Observable 完成后检查我的 spy ?

最佳答案

我不知道您如何在组件上配置服务,但当我覆盖从 TestComponentBuilder 创建的组件的提供者时,它对我有用。

让我们举个例子。我有一个返回字符串列表的服务:

import {Observable} from 'rxjs/Rx';

export class MyService {
getDogs() {
return Observable.of([ 's1', 's2', ... ]);
}
}

组件使用此服务在单击按钮时异步显示列表:

@Component({
selector: 'my-list',
providers: [MyService],
template: `
<ul><li *ngFor="#item of items">{{ item }}</li></ul>
<div id="test" (click)="test()">Test</div>
`
})
export class MyList implements OnInit {
items:Array<string>;
service:MyService;

constructor(private service:MyService) {
}

test() {
this.service.getDogs().subscribe(
(dogs) => {
this.items = dogs;
});
}
}

我想测试点击“测试”按钮时,调用组件的test方法,间接调用服务的getDogs方法.

为此,我创建了一个直接实例化服务并使用 TestComponentBuilder 加载组件的测试。在这种情况下,我需要在调用 createAsync 之前对其调用 overrideProviders 方法。通过这种方式,您将能够提供您的 spy 服务以收到调用通知。这是一个示例:

let service:MyService = new MyService();

beforeEach(() => {
spyOn(service, 'getDogs').and.returnValue(Observable.of(
['dog1', 'dog2', 'dog3']));

});

it('should test get dogs', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb.overrideProviders(MyList, [provide(MyService, { useValue: service })])
.createAsync(MyList).then((componentFixture: ComponentFixture) => {
const element = componentFixture.nativeElement;
componentFixture.detectChanges();

var clickButton = document.getElementById('test');
clickButton.dispatchEvent(new Event("click"));

expect(service.getDogs).toHaveBeenCalled();
});
}));

编辑

由于事件是异步触发的,您可以考虑使用fakeAsync。后者允许您完全控制何时处理异步处理并将异步事物转换为同步事物。

您可以将您的测试处理包装到

fakeAsync((): void => {
var clickButton = document.getElementById('test');
clickButton.dispatchEvent(new Event("click"));

expect(service.getDogs).toHaveBeenCalled();
});

更多细节,你可以看看这个问题:

关于javascript - Jasmine:用事件测试 observables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36422160/

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