Asynchronous 测试异步管道转换 上下文
我有一个基本的Asynchronous 测试异步管道转换 上下文,asynchronous,angular,jasmine,angular2-testing,angular2-pipe,Asynchronous,Angular,Jasmine,Angular2 Testing,Angular2 Pipe,我有一个基本的PipeTransform,希望它是异步的。为什么?因为我有自己的i18n服务(由于解析、复数化和其他限制,我自己做了),它返回一个承诺: 这个管道工作得很好,因为唯一延迟的调用是第一个调用(I18N服务使用延迟加载,它只在找不到键的情况下加载JSON数据,因此基本上,第一个调用会延迟,其他调用是即时的,但仍然是异步的) 问题 我不知道如何使用Jasmine测试这个管道,因为它在一个组件中工作,我知道它可以工作,但这里的目标是使用Jasmine对它进行全面测试,这样我可以将它添加到
PipeTransform
,希望它是异步的。为什么?因为我有自己的i18n服务(由于解析、复数化和其他限制,我自己做了),它返回一个承诺
:
这个管道工作得很好,因为唯一延迟的调用是第一个调用(I18N服务使用延迟加载,它只在找不到键的情况下加载JSON数据,因此基本上,第一个调用会延迟,其他调用是即时的,但仍然是异步的)
问题
我不知道如何使用Jasmine测试这个管道,因为它在一个组件中工作,我知道它可以工作,但这里的目标是使用Jasmine对它进行全面测试,这样我可以将它添加到CI例程中
上述测试:
describe("Pipe test", () => {
it("can call I18n.get.", async(inject([I18n], (i18n:I18n) => {
let pipe = new I18nPipe(i18n);
expect(pipe.transform("nope", {key: 'test', domain: 'test domain'})).toBe("test value");
})));
});
由于i18n服务提供的结果是异步的,因此返回的值在同步逻辑中未定义,因此失败
I18n管道测试可以调用I18n.get。失败
预期未定义为“测试值”
编辑:一种方法是使用
setTimeout
,但我想要一个更漂亮的解决方案,以避免在任何地方添加setTimeout(myAssertion,100)
。使用@angular/core/testing
中的fakeAsync
。它允许您调用tick()
,这将等待所有当前排队的异步任务完成后再继续。这给人一种动作同步的错觉。在调用tick()
之后,我们就可以编写我们的期望
import { fakeAsync, tick } from '@angular/core/testing';
it("can call I18n.get.", fakeAsync(inject([I18n], (i18n:I18n) => {
let pipe = new I18nPipe(i18n);
let result = pipe.transform("nope", {key: 'test', domain: 'test domain'});
tick();
expect(result).toBe("test value");
})));
那么我们什么时候应该使用fakeAsync
,什么时候应该使用async
?这是我(大多数时候)遵循的经验法则。当我们在测试中进行异步调用时,我们应该使用async
<代码>异步允许继续测试,直到所有异步调用完成。比如说
it('..', async(() => {
let service = new Servce();
service.doSomething().then(result => {
expect(result).toBe('hello');
});
});
在非async
测试中,预期永远不会发生,因为测试将在承诺的异步解析之前完成。通过调用async
,测试被包装在一个区域中,该区域跟踪所有异步任务,并等待它们完成
当异步行为不在测试的控制范围内时(如在管道中进行的情况),请使用
fakeAsync
。在这里,我们可以通过调用tick()
强制/等待它完成<代码>勾选也可以传递毫秒延迟,以便在需要时允许更多的时间传递
另一个选项是模拟服务并使其同步,如中所述。当进行单元测试时,如果您的测试中的组件依赖于服务中的大量逻辑,那么测试中的组件将受服务正常工作的支配,这有点违背了“单元”测试的目的。模拟在很多情况下都有意义。另一个涉及的问题是管道的转换只调用一次,因此返回基本上总是未定义的。我通过在测试文件中创建一个递归方法修复了这个问题,该方法允许我调用管道转换,只要我没有定义结果,就可以使用maxium调用堆栈。
it('..', async(() => {
let service = new Servce();
service.doSomething().then(result => {
expect(result).toBe('hello');
});
});