首先,我不认为这是重复的,因为SO问题和答案描述了angular1中对promise处理的测试,并且通过调用解决了$timeout.flush()
,$rootScope.$apply()
因此不适用于此Angular2案例。
我的问题是,如何解决promise后测试正在执行的Angular2组件的逻辑。(最好是茉莉花)。
为了说明这一点,我修改了Angular2文档中的快速入门示例。简单的组件列出了现有的英雄,并允许注册一个新的英雄。英雄列表和注册由服务完成,该服务以承诺(带有英雄列表或新注册的英雄对象)的形式返回响应。
现在,一旦注册了新的英雄(并解决了Promise),我希望组件使英雄成为选中状态并再次检索英雄列表:
...
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);
}
我将注册分为两种方法,因此可以在不进行服务存根的情况下对其进行测试
结合使用Jasmine异步测试,done()
我可以轻松测试服务行为,即。它返回正确的承诺。但是如何测试,该组件被调用getHeros
以刷新其列表或正确设置所选英雄。
我设法测试与规范设置变量:
it("postRegistration sets selectedHero as registered one",done =>{
let promise = service.registerHero("Bosek"); //Promise.resolve(hero);
component.postRegistration(promise);
promise.then( hero => {
expect(component.selectedHero).toBe(hero);
expect(component.heroes.indexOf(hero)).toBeGreaterThan(0);
done();
})
})
我将自己的主张“钩住”了传递给该组件的相同诺言。
我的第一个问题是:是幸运还是可以保证,如果我同意相同的诺言并从其'then'子句中调用jasmine done(),它将等到我的其他“订户”(在这种情况下为组件)处理诺言和后续的。
其次,是否有一种方法可以在测试过程中强制所有Promise同步,从而解决了整个问题。
我发现了模拟承诺项目https://github.com/charleshansen/mock-promises,该项目可以“兑现”承诺,但已经失效了2年。
这个问题应该足够普遍才能得到标准答案。
我是在Angular2和Jasmine的背景下询问的,但是,我也对简单的“单元测试”方法感兴趣,例如当前的测试完全独立于Angular框架。请输入打字稿,因为我通常不使用JS。
整个代码(是Angular2 Hero快速入门示例的简单克隆)位于:https : //github.com/tzielins/angular-start-project
@Gunter的答案使我走上了正确的道路,但由于他未明确解决问题,因此我正在编写自己的答案。
我的第一个问题
我确实只是很幸运。后续调用相同的诺言对先前的诺言没有任何影响。尽管此测试通过了,但其他具有类似模式的测试却失败了。
从“ bussiness”方法返回promise并链接到该方法并不总是一种选择,因为它取决于方法的逻辑,因此,并非总是可以遵循Gunter的建议。
其次
Gunter提到了Angular2 fakeAsync,这是测试Promise处理副作用的正确方法。尽管它是angular2测试库的一部分,但由于它不需要注入或其他角度依赖性,因此可以“单元测试”方式使用。
使用它,电话flushMicrotasks
里面fakeAsync
的身体和试验的副作用:
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);
...
}));
tick()
对诺言有类似的效果。
即使是在业务方法内部创建的新承诺也可以保证得到兑现。我在这里问了这个问题:fakeAsync是否保证在tick / flushMicroservice之后会完成承诺,而且我还发现了可证实这一点的Angular测试规范。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句