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);

现在为了测试第二种情况,我需要创建另一个始终已解决的虚假 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/46797410/

相关文章:

javascript - 为什么我的带有 Promise 的递归函数只等待一次?

javascript - 无法调用 Parse.Promise._continueWhile

javascript - 创建一个调用 Promise 或快速完成操作的方法

javascript - 引用错误 : Papa is not defined

javascript - 将相应的 JS 文件添加到新的 Vue.js 组件中

javascript - jquery post调用函数n次,但在调用下一个之前等待每个完成

javascript - 当 html 内容包含使用 css 加载的图像时,ng-bind-html 不起作用

javascript - Angular vs vanilla javascript vs jquery,我应该只使用其中之一吗?

javascript - 在 AngularJS 中相对于其他元素动态转换元素

javascript - 如何在每个矩形端点画圆