无极解决了angularjs茉莉测试为时已晚 [英] Promise resolved too late in angularjs jasmine test

查看:148
本文介绍了无极解决了angularjs茉莉测试为时已晚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了下面的测试茉莉与 NG-描述运行人缘

I have the following jasmine test written with ng-describe, run with karma.

(我使用PhantomJS ES6-承诺填充工具)

(I am using es6-promise polyfill for PhantomJS)

var myModule = angular.module('MyModule', []);
myModule.service('MyService', [function() {
  return {
    getItems: function() {
      // this will be spied and mocked
    }
  };
}]);

myModule.controller('MyController', ['$scope', 'MyService',
  function($scope, MyService) {
    $scope.items = [];

    $scope.refreshItems = function() {
      MyService.getItems().then(
        function ok(items) {
          $scope.items = items;
          console.log('OK, items.length = ' + items.length);
        },
        function fail(reason) {
          console.error('FAIL')
        }).catch(console.error.bind(console));
    };
  }
]);

ngDescribe({
  name: "MyController test",
  modules: ['MyModule'],
  inject: ['MyService', '$rootScope', '$q'],
  controllers: 'MyController',
  tests: function(deps) {

    function getPromise(val) {
      return new Promise(function(resolve, reject) {
        resolve(val);
      });
    }

    it('updates $scope.items', function() {
      spyOn(deps.MyService, 'getItems').and.returnValue(getPromise([4, 5, 6]));
      deps.MyController.refreshItems();
      deps.$rootScope.$digest();

      expect(deps.MyService.getItems).toHaveBeenCalled();
      expect(deps.MyController.items.length).toBe(3);
      console.log("END OF TEST");
    });
  }
});

该测试将失败,因为承诺解决太晚了:

The test would fail because the promise is resolved too late:

LOG: 'END OF TEST'
PhantomJS 1.9.8 (Windows 7 0.0.0) MyController test updates $scope.items FAILED
        Expected 0 to be 3.
            at d:/git/myproject/test/controllers/ItmngtControllerTest.js:49
LOG: 'OK, items.length = 3'
PhantomJS 1.9.8 (Windows 7 0.0.0): Executed 37 of 37 (1 FAILED) (0.085 secs / 0.26 secs)

在太长时间的调查,我想它,如果我用 $ Q 而不是无极,它会工作罚款。

After too long investigation, I figured it that if I use $q instead of Promise, it will work fine.

    function getPromise(val) {
      var deferred = deps.$q.defer();
      deferred.resolve(val);
      return deferred.promise;
    }

不过,我想知道,为什么是这样的话,我可以改变的东西在我的测试中使用无极而不是 $ Q <的/ code>来使测试通过?

I'm wondering however, why is this the case, and can I change something in my test to use Promise instead of $q to make the test pass?

我读过在不同的地方约 $ rootScope。$适用(),但无论我把它,它仍然不为我工作。

I've read in various places about $rootScope.$apply() but wherever I put it, it still doesn't work for me.

推荐答案

$ Q 测试是同步的,这是一个巨大的优势。一旦范围 $消化()被调用,可以预期,所有的 $ Q 承诺链中处理程序也被调用。

Angular $q testing is synchronous, which is a huge advantage. Once scope $digest() was called, the one can expect that all $q promise chain handlers were called also.

承诺在一般(包括ES6实现)是通过设计异步,另一方面。一旦承诺就解决了,它的处理器将在下一次滴答被调用。那么愉快角测试是不是同步的了:

Promises in general (including ES6 implementation) are asynchronous by design, on the other hand. Once the promise was resolved, its handlers will be called on the next tick. So pleasant Angular testing is not that synchronous anymore:

it('updates $scope.items', function (done) {
  ...
  setTimeout(() => {
    expect(deps.MyService.getItems).toHaveBeenCalled();
    expect(deps.MyController.items.length).toBe(3);
    console.log("END OF TEST");
    done();
  });
});

无极可以嘲笑为测试目的是同步的,的 模拟承诺 可能在这种情况下使用。

Promise can be mocked for testing purposes to be synchronous, mock-promises may be used in this case.

和有 茉莉合作 其目的是进行异步测试的茉莉花容易多了(它实际上)与ES6发电机和,我不知道它有多好与<$ C $执行C> NG-描述

And there is jasmine-co which is intended to make asynchronous testing in Jasmine easier (and it actually does) with ES6 generators and co, I'm not aware how good it performs with ng-describe.

这篇关于无极解决了angularjs茉莉测试为时已晚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆