【发布时间】:2017-07-12 13:05:19
【问题描述】:
您好,我有一个使用 AngularJS (1.5.11) 编写的功能完整的网络应用程序,现在我开始使用 karma (0.12.37)、grunt-karma (0.8.3)、karma-chrome 进行单元测试-launcher (0.1.12), karma-phantomjs-launcher (1.0.4), phantomjs-prebuilt (2.1.14), jasmine-promise-matchers (2.3.0) 和 karma-jasmine ( 0.1.6),带有 1.3.x Jasmine 版本。
我对测试异步的东西不是很有信心,所以我开始四处搜索,我总是看到运行 AngularJS 异步测试的唯一强制性内容是在调用异步函数之后的 $rootScope/$scope.$apply/$digest。
最终我发现someone suggesting me to use runs() and waitsFor() 和plunkr 中的测试在使用chrome-launcher 时运行顺利,但在使用phantomjs-launcher 时失败,抛出如下错误:
Expected { myError : { error : 'error_message' }, line : <factory's line of code which throws the error>, sourceURL : 'path/to/factory.js', stack :
<function throwing error> B@path/to/factory.js:<factory's line of code which throws the error>
<"async" function> A@path/to/factory.js:<factory's line of code which calls B()>
path/to/factory-spec.js:<the following line of code: var promise = HandleService.A();>
invoke@path/to/angular/angular.js:4771:24
WorkFn@path/to/angular-mocks/angular-mocks.js:3130:26
execute@path/to/node_modules/karma-jasmine/lib/jasmine.js:1145:22
next_@path/to/node_modules/karma-jasmine/lib/jasmine.js:2177:38
start@path/to/node_modules/karma-jasmine/lib/jasmine.js:2130:13
execute@path/to/node_modules/karma-jasmine/lib/jasmine.js:2458:19
next_@path/to/node_modules/karma-jasmine/lib/jasmine.js:2177:38
start@path/to/node_modules/karma-jasmine/lib/jasmine.js:2130:13
execute@path/to/node_modules/karma-jasmine/lib/jasmine.js:2604:19
next_@path/to/node_modules/karma-jasmine/lib/jasmine.js:2177:38
start@path/to/node_modules/karma-jasmine/lib/jasmine.js:2130:13
execute@path/to/node_modules/karma-jasmine/lib/jasmine.js:2604:19
next_@path/to/node_modules/karma-jasmine/lib/jasmine.js:2177:38
onComplete@path/to/node_modules/karma-jasmine/lib/jasmine.js:2173:23
finish@path/to/node_modules/karma-jasmine/lib/jasmine.js:2561:15
path/to/node_modules/karma-jasmine/lib/jasmine.js:2605:16
next_@path/to/node_modules/karma-jasmine/lib/jasmine.js:2187:24
onComplete@path/to/node_modules/karma-jasmine/lib/jasmine.js:2173:23
finish@path/to/node_modules/karma-jasmine/lib/jasmine.js:2561:15
path/to/node_modules/karma-jasmine/lib/jasmine.js:2605:16
next_@path/to/node_modules/karma-jasmine/lib/jasmine.js:2187:24
onComplete@path/to/node_modules/karma-jasmine/lib/jasmine.js:2173:23
finish@path/to/node_modules/karma-jasmine/lib/jasmine.js:2432:15
path/to/node_modules/karma-jasmine/lib/jasmine.js:2459:16
next_@path/to/node_modules/karma-jasmine/lib/jasmine.js:2187:24
path/to/node_modules/karma-jasmine/lib/jasmine.js:2167:23' }, pending : undefined, processScheduled : false } } to be rejected with { myError : { error : 'error_message' } }.
所以我开始认为 Chrome 结果是误报,我需要重写异步测试:因此我尝试了类似 plunkr 的东西,但现在 PhantomJs 和 Chrome 中的测试都失败了,并出现了预期的超时消息:
timeout: timed out after 1500 msec waiting for A should catch an error
注意: 我现在无法将 Jasmine 更新到 2.0 版并使用 done 参数机制,如果我做对了,我什至不应该手动触发$rootScope.$apply/$digest 使用 jasmine-promise-matchers 时。
我怎样才能为这种捕获自定义错误的异步函数和一般的异步函数正确编写异步测试?
【问题讨论】:
-
离题:不要从过时的测试框架开始。使用茉莉花〜2.6。请不要回复,拿去吧。 Ontopic:我发现您的问题太宽泛/不清楚:我在问题中看不到任何代码(the volatilePlunkr 链接不算在内)。即使是 Plunkr 也不够 mcve。指南:请注意,如果完成,测试运行程序可能无法处理任何
expect()ations。你必须usewaitsFor()andruns()。测试承诺状态或设置标志 -
Offtopic:... Ontopic:事实是我不知道如何在 plunkr 中设置类似于我的测试环境的东西(这就是为什么我链接了有关所涉及的 grunt 任务的所有信息),但是正如我所说的this gentleman already told me I should use waitsFor() and runs(), I got it,因此我“尽最大努力”提供了一个plunkr。
-
这位先生错了,对事情的运作方式没有信心。在 AngularJS 测试中你很少需要
done- 更重要的是,runs/waitsFor 这种气味更糟。 -
@estus 有趣,你是在告诉我,好先生,我不会在我的 AngularJS 异步测试中使用 runs() 和 waitsFor() 吗?那么我该如何写我写的那个不会产生误报或任何东西的方式呢?
-
@MichaelRadionov 这里的重点是 $q 承诺本身没有异步行为。它们是同步的(只要它们承诺的代码是同步的),这以及它们与范围摘要的连接确实不同于其他承诺实现。根据我对 Angular 内部结构的了解,$q 和其他内置服务正是这样构建的,目的是让 Jasmine 测试更简洁、更快速。
标签: javascript angularjs unit-testing asynchronous jasmine