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。你有使用蓝鸟或其他替代品的经验吗?我刚才写了一篇关于它的问答,谢谢!如果这是我的选择,我会尝试一下。