为什么我在Jasmine 1.3.x中的AngularJS异步测试不起作用?

时间:2017-07-12 13:05:19

标签: javascript angularjs unit-testing asynchronous jasmine

您好我有一个功能完整的网络应用程序使用AngularJS(1.5.11)编写,现在我开始使用业力(0.12.37),grunt-karma(0.8.3),业力进行单元测试-chrome-launcher(0.1.12),karma-phantomjs-launcher(1.0.4), phantomjs-prebuilt (2.1.14),jasmine-promise-matchers(2.3.0)和karma-茉莉花(0.1.6),含有1.3.x茉莉花版。

我对测试异步内容不太自信,所以我开始google搜索并且我总是看到在异步函数发生后立即运行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

NB: 我无法将Jasmine更新到2.0版并立即使用done参数机制,如果我做对了,我不应该甚至在使用jasmine-promise-matchers时手动触发$rootScope.$apply/$digest

如何正确编写异步测试以获取此类异常函数以捕获自定义错误和异步函数?

1 个答案:

答案 0 :(得分:2)

Angular'async'测试通常是同步的,因此waitsForruns是不必要的并且显然是有害的。

实际上,jasmine-promise-matchers不需要手动触发摘要来执行$ q promises,因为这是在内部完成的。

这里的问题是竞争条件。第一个runs似乎在$rootScope.$digest()之后运行,catch块永远不会执行 - 因此是第二个runs

相反,它应该同步测试:

  it('it actually throws an error, yay', function () {
    var promise = HandleService.A();

    expect(promise).toBePromise();
    expect(promise).toBeRejectedWith(jasmine.objectContaining({
      myError: {error: 'error_message'}
    }));
  });