angular modal ui bootstrap unit test - undefined不是一个函数

时间:2015-01-29 16:50:10

标签: angularjs unit-testing angular-ui-bootstrap

APP

(function() {
'use strict';

function ArticlesController($templateCache, $modal, articlesData, Articles, $state) {
  var articles = this;
  articles.data = articlesData.data;
  console.log($modal);//Give me LOG: Object{open: function () { ... }}
  articles.open = function (article) {
    var modalInstance = $modal.open({ // The unit test point to this line
      template:  $templateCache.get('articles/templates/modalDestroy.html'),
      controller: 'ArticleDestroyController',
      controllerAs: 'article',
      size: 'sm',
      resolve: {
        articleData: function(){
          return article;
        }
    }
    });
    modalInstance.result.then(function (article) {
      Articles.destroy(article._id).then(function(response) {
        var data = [];
        angular.forEach(articles.data, function(value, key) {
          if( value._id !== article._id){
            this.push(value);
          }
        }, data);
        articles.data = data;
      })
      .catch(function(response) {
        console.log(response);
      });

    });
  };
}

function ArticleDestroyController($modalInstance, articleData, Articles) {
  var article = this;
  article.data = articleData;
  article.ok = function () {
    $modalInstance.close(articleData);
  };
  article.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
}
angular.module('articles.controllers', [])
    .controller('ArticlesController', ArticlesController)
    .controller('ArticleDestroyController', ArticleDestroyController);
})();

TEST

'use strict';

/* global describe, beforeEach,  it, before,  after, afterEach, inject, expect, spyOn */

describe('Unit: ArticlesController', function() {
    var $rootScope, $scope, $controller;

    beforeEach(function() {
        module('articles');
    });
    var fakeModal = {
        result: {
            then: function(confirmCallback, cancelCallback) {
                //Store the callbacks for later when the user clicks on the OK or Cancel button of the dialog
                this.confirmCallBack = confirmCallback;
                this.cancelCallback = cancelCallback;
            }
        },
        close: function( item ) {
            //The user clicked OK on the modal dialog, call the stored confirm callback with the selected item
            this.result.confirmCallBack( item );
        },
        dismiss: function( type ) {
            //The user clicked cancel on the modal dialog, call the stored cancel callback
            this.result.cancelCallback( type );
        }
    }; 

    beforeEach(inject(function($modal) {
        spyOn($modal, 'open').and.callFake(fakeModal);
    })); 

    beforeEach(inject(function(_$rootScope_,_$controller_, $modal){
        $rootScope = _$rootScope_;
        $scope = $rootScope.$new();
        $controller = _$controller_;
        var articlesData = {data:[{title:'my title',content:'my content'}]};
        $controller('ArticlesController as articles', {$scope: $scope, $modal: $modal, articlesData:articlesData});
    }));


    it('articles.data should create an array with at least one article object ', function() {
         expect($scope.articles.data.length).toBe(1);

         $scope.articles.open($scope.articles.data[0]);
    });

});

当我运行gulp单位时 我有

TypeError: undefined is not a function
        at ArticlesController.articles.open 

指向第9行

var modalInstance = $modal.open

但如果我尝试检查$ modal它会给我

console.log($modal);//Give me LOG: Object{open: function () { ... }}

你看到了什么问题吗?

1 个答案:

答案 0 :(得分:2)

spyOn($modal, "open").and.callFake(function() {
    return fakeModal;
});

在工作中遇到这个问题并根据Jasmine 2.0(http://jasmine.github.io/2.0/introduction.html)的文档以这种方式解决它。