单元测试有望在AngularJS控制器 [英] Unit testing promises in controllers in AngularJS

查看:167
本文介绍了单元测试有望在AngularJS控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们最近开始将承诺在我们的控制器在同一时间处理多个请求,它工作在应用程序,但单元测试,这些已被证明是比困难多,我会我也很难把握到底是什么被我错过了。以下是被什么,我究竟想要测试非常简化的2段。

We recently started incorporating promises in our controllers to handle multiple requests at the same time and it works in the app, but unit testing these has been proven to be more than difficult and I will I have a hard time grasping exactly what it is I'm missing. Following are two snippets that are very simplified on what I'm exactly trying to test.

控制器:

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

根据所有实例和文档,我的承诺和$ Q阅读,这应该工作,但它并没有,而是我得到:

According to all examples and documentation I've read on promises and $q, this should work, but it doesn't, instead I get:

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

我猜,因为它是不一样的递延对象,我解决我的嘲笑间谍,但我怎么想嘲笑吗?我必须在控制器上的延迟对象或范围或绑定了什么?

I'm guessing because it's not the same deferred object I'm resolving in my mocked spy, but how am I suppose to mock that? Do I have to bind the deferred object on the controller or the scope or what?

原因你看到的结构是因为有使用getTest()方法不同(有的不仅使用要求,也是别人的,因此承诺)。此外,getTest()是另一个测试,这就是为什么我想嘲弄的功能和它的任何请求单独测试。

The reason for the structure you see is because there are different methods using getTest() (and some do not only use that request but also others, hence promises). Also, getTest() is tested separately in another test, which is why I want to mock that function and any requests made in it.

任何帮助是AP preciated,如果我做了一些明显的错误,我很高兴地教育自己仍是相当新的角度。

Any help is appreciated and if I've made some blatant errors, I'm happy to educate myself being still fairly new to Angular.

推荐答案

是的,你是不是解决权的承诺。你需要拦截的函数参数。

Yes, you are not resolving the right promise. You need to intercept the function arguments.

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

这是一个很好的简洁茉莉花参考: http://tobyho.com / 2011/12/15 /茉莉间谍的cheatsheet /

This is a good concise Jasmine reference: http://tobyho.com/2011/12/15/jasmine-spy-cheatsheet/

这篇关于单元测试有望在AngularJS控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆