如何用 spyOn 测试承诺的功能



我是编码新手,所以请询问是否需要更多信息。

我想用 spyOn 在 Promise.all 中测试一个 then-block,但该函数从未被调用。

public foo(): void {
const names = this.getNames();
Promise.all(
names.map(name =>
this.nameService.doSomething( //some params )
)
)
.then(result => this.controller.ok(names))
.catch(error => {
//do something
});
}

这是考验

it('should call controller.ok when name is set', () => {
spyOn(nameService, 'doSomething').and.returnValue(Promise.resolve());
spyOn(controller, 'ok');
service.foo();
expect(nameService.doSomething).toHaveBeenCalledWith({
//some params
});
expect(controller.ok).toHaveBeenCalled(); //fails because never called
});

我已经调试了代码,即使使用正确的参数也会调用doSomething,代码也会到达then块。 但是测试说,它永远不会被调用,所以在某个地方代码中断了,我不知道为什么?

不调用捕获块。

表示异步操作最终完成或失败的承诺。在测试中,检查是否已调用controller.ok时,尚未解析方法fooPromise.all返回的Promise。因此,您需要某种同步。

一种可能的解决方案如下所示。

it('should call controller.ok when name is set', () => {
const promises: Promise<any>[] = [];
spyOn(nameService, 'doSomething').and.callFake(n => {
const promise = Promise.resolve();
promises.push(promise);
return promise;
});
spyOn(controller, 'ok');
service.foo();
Promise.all(promises)
.then(r => expect(controller.ok).toHaveBeenCalled());
});

使用fakeAsynctick也可以实现相同的@angular/core/testing.

it('should call controller.ok when name is set', fakeAsync(() => {
spyOn(nameService, 'doSomething').and.returnValue(Promise.resolve());
spyOn(controller, 'ok');
service.foo();
tick();
expect(controller.ok).toHaveBeenCalled();
}));

最新更新