javascript - AngularJS Controller 中的单元测试 promise

标签 javascript angularjs unit-testing jasmine

我们最近开始在 Controller 中加入 promise ,以同时处理多个请求,并且它可以在应用程序中工作,但是单元测试已被证明非常困难,我将很难准确掌握它的含义是我失踪了。以下是两个片段,它们非常简化了我正在尝试测试的内容。

Controller :

angular.module('testengine').controller('testController', [
  '$scope', 
  '$q', 
  'Api', 
  function($scope, $q, Api) {
    $scope.getTest = function (deferred) {

      // do stuff...

      Api.test.get(params, function(response) {
        // do stuff with response

        if (deferred) {
          deferred.resolve(); // if success
        }
      });

    };

    $scope.runTest = function () {

       // do stuff...

       var promises = [];
       var deferred = $q.defer();

       promises.push(deferred.promise);
       $scope.getTest(deferred);

       $q.all(promises).then(function () {
         $scope.navigate();
       }, function () {
         // do stuff with rejected
       });

    };

    $scope.navigate = function () {
      // do stuff
    };
  }]);

测试:

describe('Controller:', function () {

  var root, scope, controllerFactory, $q;

  function createController () {
    return controllerFactory('testController', {
      $scope: scope
    });
  }

  beforeEach(function () {
    module('testengine');
  });

  beforeEach(inject(function ($rootScope, $controller, _$q_) {
    root = $rootScope;
    scope = $rootScope.new();
    controllerFactory = $controller;
    $q = _$q_;
  });

  it('should run test', function () {
    createController();

    var deferred = $q.defer();
    spyOn(scope, 'getTest').andReturn(deferred.resolve());
    spyOn(scope, 'navigate');

    $scope.runTest();

    root.$apply();
    expect(scope.navigate).toHaveBeenCalled();
  });
});

根据我读过的关于 Promise 和 $q 的所有示例和文档,这应该可行,但事实并非如此,相反我得到:

Expected spy navigate to have been called but it was never called.

我猜测是因为它与我在模拟 spy 中解析的延迟对象不同,但我该如何模拟它呢?我是否必须将延迟对象绑定(bind)到 Controller 或范围或其他什么上?

您看到的结构的原因是因为有不同的方法使用 getTest() (有些方法不仅使用该请求,还使用其他方法,因此是 promise )。另外, getTest() 在另一个测试中单独测试,这就是为什么我想模拟该函数以及其中发出的任何请求。

感谢任何帮助,如果我犯了一些明显的错误,我很乐意自学,因为我对 Angular 还很陌生。

最佳答案

是的,您没有兑现正确的 promise 。您需要拦截函数参数。

spyOn(scope, 'getTest');
expect(scope.getTest).toHaveBeenCalled();
scope.getTest.mostRecentCall.args[0].resolve();

这是一个很好的简洁 Jasmine 引用:http://tobyho.com/2011/12/15/jasmine-spy-cheatsheet/

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

相关文章:

javascript - AngularJS 指令运行时绑定(bind)

java - 在 junit 测试期间禁用记录器?

swift - 无法在 SKProductsResponse 模拟中设置 invalidProductIdentifiers

javascript - Spring MVC CSS 和 JS 未加载

javascript - 如何交错流(有背压)

javascript - 来自数组 1 输出而不是 2 的随机输出

angularjs - 使用 ng-click 或 ng-model 获取按钮值

javascript - 在 Angular Controller 中,如何在初始化另一个属性之前获取多个异步属性进行初始化

C# Windows 窗体单元测试

调用函数的 Javascript 对象名称?