【问题标题】:Testing callback from service in an AngularJS controller spec在 AngularJS 控制器规范中测试来自服务的回调
【发布时间】:2015-05-26 18:11:19
【问题描述】:

我有一个控制器,它使用的服务在成功时具有回调函数。

控制器功能

itemCtrl.save = function () {
    ItemService.save({ username: SessionService.getUsername() }, itemCtrl.item, function (res) {
        $scope.$emit('UPDATE_ITEMS');
        $modalInstance.close(res);
    });
};

规格

it('should close the modal on successful save', function () {
    spyOn(itemSrv, 'save').and.callFake(function () {
        deferred = q.defer();
        deferred.resolve();
        return deferred.promise;
    });
    spyOn(modalInst, 'close').and.callThrough();
    ItemCtrl.save();
    scope.$digest();
    expect(modalInst.close).toHaveBeenCalled();
});

当我在 karma 中运行此测试时失败,因为未调用 modalinstance 的关闭函数。我认为问题出在规范描述上,因为该功能在应用程序中运行。 我对此有几个问题:

  • 这是描述控制器中服务调用回调的最佳方式吗?
  • 我应该如何使用回调来描述我的规范?

-- 编辑--

我更改了我的服务调用,使它们将结果作为承诺处理:

itemCtrl.save = function () {
    ItemService.save({ username: SessionService.getUsername() }, horas.trabajo).$promise.then(function (res) {
        $scope.$emit('UPDATE_ITEMS');
        $modalInstance.close(res);
    });
};

我想我没有通过测试,因为我的服务没有返回一个承诺(它有一个承诺属性,我调用它来发出事件并关闭 modalInstance)。但是我仍然对如何使用 ng-resource 返回一个承诺感到困惑。

我尝试解决它是返回一个带有 $promise 属性的对象,其中包含 q 提供的承诺。

规格

it('should close the modal on successful save', function () {
    spyOn(itemSrv, 'save').and.callFake(function () {
        deferred = q.defer();
        deferred.resolve();
        return {$promise: deferred.promise};
    });
    spyOn(modalInst, 'close').and.callThrough();
    ItemCtrl.save();
    scope.$digest();
    expect(modalInst.close).toHaveBeenCalled();
});

【问题讨论】:

    标签: javascript angularjs mocking jasmine


    【解决方案1】:

    您混淆了 Promise 和回调的概念,但要让它像您目前拥有的那样工作,您可以使用:

    spyOn(itemSrv, 'save').and.callFake(function (params, callback) {
        callback({some: 'response'});
    });
    

    回调

    您传入一个将根据场景调用的函数

    承诺

    取回一个包含方法的对象(然后),该方法将在成功时调用第一个参数或在错误时调用第二个参数

    两者都有更多内容,但这是一个总体概述。

    另外,我建议更改服务中的 save 方法以返回承诺而不是接受回调。

    【讨论】:

    • 如果我更改它并返回一个承诺,我应该能够像我在问题中所做的那样进行测试,对吧?
    • 是的,你那里的测试代码应该是一样的
    • 我已经在第一篇文章的底部添加了解决它的尝试,我想我对 promises 和 ng-resource 有点困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-26
    • 2012-05-20
    • 2013-06-02
    相关资源
    最近更新 更多