javascript - Angularjs 中基于 promise 的单元测试代码

标签 javascript angularjs promise

我很难尝试在 Angularjs 中测试基于 promise 的代码。

我的 Controller 中有以下代码:

    $scope.markAsDone = function(taskId) {
        tasksService.removeAndGetNext(taskId).then(function(nextTask) {
            goTo(nextTask);
        })
    };

    function goTo(nextTask) {
        $location.path(...);
    }

我想对以下情况进行单元测试:

  • markAsDone 被调用时,它应该调用 tasksService.removeAndGetNext
  • tasksService.removeAndGetNext 完成后,它应该改变位置(调用 goTo)

在我看来,没有简单的方法来分别测试这两种情况。

我为测试第一个所做的是:

var noopPromise= {then: function() {}}
spyOn(tasksService, 'removeAndGetNext').andReturn(noopPromise);

现在要测试第二种情况,我需要创建另一个始终resolved 的虚假 promise 。这一切都非常乏味,而且有很多样板代码。

还有其他方法可以测试这些东西吗?还是我的设计有味道?

最佳答案

您仍然需要模拟服务并返回一个 promise ,但您应该使用真正的 promise ,这样您就不需要实现它的功能。使用 beforeEach 来创建已经实现的 promise ,并在您需要它始终得到解决时模拟该服务。

var $rootScope;

beforeEach(inject(function(_$rootScope_, $q) {
  $rootScope = _$rootScope_;

  var deferred = $q.defer();
  deferred.resolve('somevalue'); //  always resolved, you can do it from your spec

  // jasmine 2.0
  spyOn(tasksService, 'removeAndGetNext').and.returnValue(deferred.promise); 

  // jasmine 1.3
  //spyOn(tasksService, 'removeAndGetNext').andReturn(deferred.promise); 

}));

如果您更愿意在每个 it block 中用不同的值解析它,那么您只需将 deferred 暴露给局部变量并在规范中解析它。

当然,您会保持测试原样,但这里有一些非常简单的规范来向您展示它是如何工作的。

it ('should test receive the fulfilled promise', function() {
  var result;

  tasksService.removeAndGetNext().then(function(returnFromPromise) {
    result = returnFromPromise;
  });

  $rootScope.$apply(); // promises are resolved/dispatched only on next $digest cycle
  expect(result).toBe('somevalue');
});

关于javascript - Angularjs 中基于 promise 的单元测试代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16081586/

相关文章:

javascript - 文本框弹出窗口上的 Twitter Bootstrap 验证消息

javascript - "TypeError: Cannot read property ' 状态 ' of undefined"

javascript - 网络 Storm 2016.3.2 "Missing import statement"

javascript - $ionicHistory 不适用于 ionic 标签

javascript - Angular 表达式没有返回任何内容

javascript - 将 Native Promise 转换为 JQuery 的 Promise(适用于 IE)

javascript - 如何让侧边栏在 div 内滑动而不是在 body 内滑动?

javascript - 单击元素(例如一个或多个图像标签),并且应该在 angularjs 中调用相同的函数

javascript - 从另一个函数内部调用日期选择器选项函数

node.js - TypeError : invNum. next 不是一个函数