简体   繁体   English

为什么我在Jasmine 1.3.x中的AngularJS异步测试无法正常工作?

[英]Why my AngularJS async test in Jasmine 1.3.x is not working?

Hi I have a feature complete web-app written using AngularJS (1.5.11) and now I'm getting started with unit testing using 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) and karma-jasmine (0.1.6), with a 1.3.x Jasmine version. 嗨,我有一个使用AngularJS(1.5.11)编写的功能完整的Web应用程序,现在我开始使用karma(0.12.37),grunt-karma(0.8.3),karm-chrome-launcher( 0.1.12),karma-phantomjs-launcher(1.0.4), phantomjs-prebuilt (2.1.14),茉莉花承诺匹配器(2.3.0)和karma-jasmine(0.1.6),以及1.3.x茉莉花版本。

I'm not very confident in testing asynchronous stuff, so I started googling around and I always end up seeing the only mandatory thing to run AngularJS async tests is a $rootScope/$scope.$apply/$digest right after the async function has been called. 我对测试异步内容不是很有信心,所以我开始四处搜寻,最终总是看到运行AngularJS异步测试的唯一强制性要求是$rootScope/$scope.$apply/$digest被称为。

Eventually I found someone suggesting me to use runs() and waitsFor() and the test in this plunkr in particular runs smoothly when using the chrome-launcher but fails when using phantomjs-launcher, throwing an error like the following: 最终我发现有人建议我使用runs()和waitsFor() ,尤其是在使用chrome-launcher时,此plunkr中的测试可以顺利运行,但是在使用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' } }.

So I started to think Chrome results were false positive, and I needed to rewrite the async tests: hence I tried with something like this plunkr , but now the tests fail both in PhantomJs and Chrome with the expected timeout message: 因此,我开始认为Chrome的结果为假阳性,因此我需要重写异步测试:因此,我尝试使用类似plunkr的方法进行尝试 ,但是现在PhantomJs和Chrome中的测试均失败,并显示预期的超时消息:

timeout: timed out after 1500 msec waiting for A should catch an error

NB: I can't update Jasmine to version 2.0 and use the done parameter mechanism now and if I got it right I should not even manually trigger a $rootScope.$apply/$digest when using jasmine-promise-matchers . 注意: 我现在无法将Jasmine更新到2.0版并使用done参数机制 ,如果正确使用,我什$rootScope.$apply/$digest不应该在使用jasmine-promise-matchers时手动触发$rootScope.$apply/$digest

How can I write my async tests properly for this kind of async functions catching custom errors and async functions in general? 对于这种捕获自定义错误和异步函数的异步函数,如何正确编写我的异步测试?

Angular 'async' tests are generally synchronous, thus waitsFor and runs are unnecessary and apparently harmful. 角“异步”测试一般是同步的,从而waitsForruns是不必要的和有害的明显。

Indeed, jasmine-promise-matchers don't need to trigger a digest manually to execute $q promises since this is done internally. 的确, jasmine-promise-matchers不需要手动触发摘要来执行$ q promises,因为这是在内部完成的。

The problem here is race condition. 这里的问题是比赛条件。 First runs seems to run after $rootScope.$digest() , and catch block is never executed - so is second runs . 第一次runs似乎在$rootScope.$digest()之后运行,并且catch块从不执行-第二次runs也是如此。

Instead, it should be tested synchronously: 相反,应该对其进行同步测试:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM