【问题标题】:Promise is not being handled未处理承诺
【发布时间】:2014-06-17 12:44:03
【问题描述】:

我正在使用带有模拟服务的 Jasmine 为我的 Angular 应用程序编写单元测试。但是,我试图兑现的承诺不起作用。

这里是服务:

CreateItemController = $controller('CreateItemController', {
    ItemService: {

        createItem: function(data) {
            console.log('Service running');
            var defer = $q.defer();
            defer.resolve('1');
            return defer.promise;   
        }

测试:

it('should create an item', function() {

    var created = false;
    $scope.createItem().then(function(response) {
        // This is not being run                
        console.log("We got through");
        created = true;
    });

    expect(created).toBe(true);

})

最后是实际功能:

    $scope.createItem = function() {
        var postData = {
            name: 'Jeans'
        };

        return ItemService.createItem(postData).then(function(response) {
            // This is not being run                
            console.log('Promise recieved');
        });
    }

我做错了什么?

【问题讨论】:

  • $q服务注入正确了吗?
  • 是的。 inject(function($rootScope, $controller, $q) {

标签: javascript angularjs unit-testing testing jasmine


【解决方案1】:

您应该模拟 $q 服务,以便在您的测试中承诺的解决方案不再是异步。

测试 $q 服务本身没有意义,您只想测试您的自定义逻辑。

  describe('controller: CreateItemController', function () {
    var subject, $scope;
    beforeEach(module('myModule'));
    beforeEach(inject(function ($rootScope, $controller, $q) {
      $scope = $rootScope.$new();

      subject = $controller('CreateItemController', {
        $scope: $scope,
        ItemService: {
          createItem: function () {
            var defer = $q.defer();
            spyOn(defer.promise, 'then').andCallFake(function (callback) {
              callback();
              return this;
            });
            return defer.promise;
          }
        }
      });
    }));

    it('should create an item', function () {
      var created = false;
      var subject = $scope.createItem().then(function () {
        created = true;
      });

      //deferred.resolve('1'); // useless as our callbacks are called as soon as they are registered

      expect(created).toEqual(true);
    });
  });

如果您想保持延迟,您可以在解析延迟对象后调用 $scope.$apply(),如下所示:

  describe('controlle: stack overflow', function () {
    var subject, $scope, deferred;
    beforeEach(module('myModule'));
    beforeEach(inject(function ($rootScope, $controller, $q) {
      $scope = $rootScope.$new();

      subject = $controller('CreateItemController', {
        $scope: $scope,
        ItemService: {
        createItem: function () {
            deferred = $q.defer();
            return deferred.promise;
          }
        }
      });
    }));

    it('should create an item', function () {
      var expected = {
        one: false,
        two: false,
      };
      var subject = $scope.createItem();
      subject.then(function () {
        expected.one = true;
      }).then(function () {
        expected.two = true;
      });

      deferred.resolve();
      expect(expected.one).toEqual(false);
      expect(expected.two).toEqual(false);

      $scope.$apply();

      expect(expected.one).toEqual(true);
      expect(expected.two).toEqual(true);
    });
  });
});

【讨论】:

  • 我正在为你设置
猜你喜欢
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 2018-03-31
  • 2023-03-17
相关资源
最近更新 更多