Javascript AngularJs:未处理承诺的自动单元测试
假设我有一个调用两个相关异步函数的函数Javascript AngularJs:未处理承诺的自动单元测试,javascript,angularjs,Javascript,Angularjs,假设我有一个调用两个相关异步函数的函数 function targetFn() { asyncFn1(); asyncFn2(); } 这显然是一个缺陷,因为asyncFn2并不等待asyncFn1完成。正确的实施方式是: function targetFn() { asyncFn1().then(asyncFn2); } 然而,如何测试这一点?也许我会这样测试: it("ensures the ordering", function() { spyOn(windo
function targetFn() {
asyncFn1();
asyncFn2();
}
这显然是一个缺陷,因为asyncFn2
并不等待asyncFn1
完成。正确的实施方式是:
function targetFn() {
asyncFn1().then(asyncFn2);
}
然而,如何测试这一点?也许我会这样测试:
it("ensures the ordering", function() {
spyOn(window, "asyncFn1").and.callFake(function() {
return $q.reject("irrelevant");
});
spyOn(window, "asyncFn2");
$timeout.flush();
expect(asyncFn2).not.toHaveBeenCalled();
});
对于这个简单的测试用例,这是可以的。但是如果我有几个链式异步函数呢?测试工作将呈指数增长;我必须测试每一个可能的组合,拒绝和解决每一个承诺。如果我更改一个同步函数,使之成为一个异步函数,会怎么样?我会在每个被调用函数中引入缺陷行为,而不会出现任何失败的测试
我真正想要的是自动检测未处理的承诺。回到第一个例子:
function targetFn() {
asyncFn1();
asyncFn2();
}
测试系统应该认识到asyncFn1
和asyncFn2
正在创建新的承诺,但是没有then
和catch
处理程序。第二个例子当然也会失败:
function targetFn() {
asyncFn1().then(asyncFn2);
}
因为然后
引入了一个新的承诺,它不会被处理,因为它不会被返回
我想写一个测试,比如:
it("does not introduce unhandled promises", function() {
expect(targetFn).doesNotIntroduceUnhandledPromises();
});
并且它检查在执行targetFn
期间创建的每个承诺是否都有一个类似于finally
的“端点”,或者是否链接到targetFn
返回的承诺
你知道如何做到这一点吗?或者是更好的解决方案
谢谢
蒂莫
这显然是一个缺陷,因为asyncFn2并不等待asyncFn1完成。正确的实施方式是:
function targetFn() {
asyncFn1().then(asyncFn2);
}
不,不是这样,想要并行执行两个操作,甚至完全忽略一个操作的结果是很常见的:
function loadNewData() {
reportDataLoadedToGoogleAnalytics();
return dataService.loadNewData("someParameter");
}
但你的问题是,你的承诺没有得到回报。根据经验法则每当一个方法执行与承诺异步的操作时,它都应该返回一个承诺。这将有效地消除您测试有趣承诺的问题(用摩卡咖啡返回)
我真正想要的是自动检测未处理的承诺
这实际上是很有可能的,您可以使用一个功能强大的库,如bluebird,然后调出
$q
,使用它的内置设施,或者自己装饰$q。然而,当我试图做这些装饰时,它变得非常粗糙,我请求撒旦带走我的灵魂(不得不做新的错误().stack并grep它作为一个函数名)。“不,不是,想要并行执行两个操作是很常见的”。没错,但我提到异步操作应该相互依赖。如果我想并行执行它们,我会使用$q.all。经验法则是有意义的,但不是单元测试的替代品,imho。你有使用蓝鸟或其他替代品的经验吗?我刚才写了一篇关于它的问答,谢谢!如果这是我的选择,我会尝试一下。