Typescript 如何测试组件行为以响应承诺
首先,我不认为它是重复的,因为SO问题和答案描述了angular1中承诺处理的测试,并通过调用Typescript 如何测试组件行为以响应承诺,typescript,jasmine,angular,es6-promise,Typescript,Jasmine,Angular,Es6 Promise,首先,我不认为它是重复的,因为SO问题和答案描述了angular1中承诺处理的测试,并通过调用$timeout.flush()或$rootScope.$apply()解决,因此不适用于此Angular2案例 我的问题是如何测试Angular2组件的逻辑,该组件在解决承诺后执行。(最好是茉莉花) 为了说明这一点,我修改了Angular2文档中的快速入门示例。Simple component列出现有的Hero,并允许注册新的Hero。heros列表和注册由一个服务完成,该服务以承诺的形式返回响应(带
$timeout.flush()
或$rootScope.$apply()
解决,因此不适用于此Angular2案例
我的问题是如何测试Angular2组件的逻辑,该组件在解决承诺后执行。(最好是茉莉花)
为了说明这一点,我修改了Angular2文档中的快速入门示例。Simple component列出现有的Hero,并允许注册新的Hero。heros列表和注册由一个服务完成,该服务以承诺的形式返回响应(带有heros列表或新注册的hero对象)
现在,一旦注册了一个新的英雄(并解决了承诺),我希望组件选择英雄,并再次检索英雄列表:
...
register(heroName:string) {
this.postRegistration(this._heroService.registerHero(heroName));
}
//this extra method helps testing without stubing of the service
postRegistration(heroPromise:Promise<Hero>) {
heroPromise.then( hero => {
//I want to test that the two actions below took place
this.selectedHero = hero;
this.getHeroes(); })
}
getHeroes() {
this._heroService.getHeroes().then(heroes => this.heroes = heroes);
}
我将我的断言与传递给组件的承诺“挂钩”
我的第一个问题:我是幸运还是保证,如果我订阅了相同的承诺,并从其“then”子句jasmine done()调用,它将等待我的其他“订户”(在这种情况下是组件)处理该承诺和后续承诺
其次,是否有一种方法可以强制所有承诺在测试期间同步,从而解决整个问题
我发现了mock promise项目,它允许“发射”承诺,但它已经死了2年
这个问题应该足够普遍,可以有一个标准的答案
我是在Angular2和Jasmine的背景下提问的,但是,我也对简单的“单元测试”方法感兴趣,例如,当前的测试完全独立于角度框架。请输入脚本,因为我通常不使用JS
整个代码(它是Angular2 Hero快速入门示例的简单克隆)如下所示:
我的第一个问题:
你应该始终确保回报承诺
register(heroName:string) {
return this.postRegistration(this._heroService.registerHero(heroName));
}
//this extra method helps testing without stubing of the service
postRegistration(heroPromise:Promise<Hero>) {
return heroPromise.then( hero => {
//I want to test that the two actions below took place
this.selectedHero = hero;
return this.getHeroes(); })
}
getHeroes() {
return this._heroService.getHeroes().then(heroes => this.heroes = heroes);
}
寄存器(heroName:string){
返回this.postRegistration(this.\u heroService.registerHero(heroName));
}
//这个额外的方法有助于在不中断服务的情况下进行测试
注册后(承诺:承诺){
回报你的承诺。然后(英雄=>{
//我想测试以下两个动作是否发生
this.selectedHero=英雄;
返回此。getHeroes();})
}
getHeroes(){
返回此。_heroService.getheromes()。然后(heromes=>this.heromes=heromes);
}
这样,当您调用时,异步部分被链接起来。然后(…)
返回值,否则异步调用将成为它们自己的断开连接的事件链,并且您无法获得有关它们何时执行或何时完成的任何信息
其次
有一个fakeAsync应该允许进行测试
(我自己还没试过)
否则,承诺是异步的,没有什么可以改变这一点。@Gunter-answer让我走上了正确的道路,但由于他没有明确解决这个问题,我正在写我自己的答案 我的第一个问题 我真的只是幸运而已。对同一承诺做出后续呼吁,不会对之前的承诺产生任何影响。虽然这个测试通过了,但其他模式类似的测试失败了 从“business”方法返回承诺并链接到它,并不总是一个选项,因为它取决于方法逻辑,所以Gunter的建议并不总是可以遵循的 其次 Gunter提到Angular2 fakeAsync,它是测试承诺处理副作用的正确方法。尽管它是angular2测试库的一部分,但它可以以“单元测试”的方式使用,因为它不需要注入或其他角度依赖 使用它,调用
flushMicrotasks
insidefakeAsync
body并测试副作用:
import {it,fakeAsync,tick,flushMicrotasks} from 'angular2/testing';
...
it('correct side effect after processing promise',<any>fakeAsync(() => {
let p = Promise.resolve(X);
//invoking business logic
component.dealWithIt(p);
flushMicrotasks();
//now the side effects can be tested in synchronous way
expect(component.selectedHero).toBe(hero);
...
}));
从'angular2/testing'导入{it,fakeAsync,tick,flushMicrotasks};
...
信息技术(“处理承诺后正确的副作用”,我还找到了角度测试规范来证实这一点。非常感谢您指出了伪异步,这是一种方式。我只是在没有接受的情况下对您的答案进行了投票。您没有解释如何处理承诺处理后副作用测试的主要问题。承诺链接可能并不总是可能的,这取决于测试中的方法是否能够返回承诺,这取决于方法逻辑。fakeAsync是一个头奖!但您没有解释它,所以我写了自己的答案。不用担心:)。我不知道fakeAsync
。我没有使用打字脚本。我只使用Dart,我们有Future
,而不是Promise
,它们的工作原理基本相同。Dart中也有fakeAsnyc
,但我从未使用过它。在Dart中使用Future
比在TS中更容易一些。
import {it,fakeAsync,tick,flushMicrotasks} from 'angular2/testing';
...
it('correct side effect after processing promise',<any>fakeAsync(() => {
let p = Promise.resolve(X);
//invoking business logic
component.dealWithIt(p);
flushMicrotasks();
//now the side effects can be tested in synchronous way
expect(component.selectedHero).toBe(hero);
...
}));