【问题标题】:AngularJS Jasmine, test function in controllerAngularJS Jasmine,控制器中的测试功能
【发布时间】:2014-05-27 18:13:58
【问题描述】:

我正在尝试使用Jasmine 测试我的AngularJS 控制器功能。但是,我收到了TypeError: undefined is not a function

这是测试的样子:

describe('BoardController', function() {

    beforeEach(module('examtesting'));

    var BoardController;

    beforeEach(inject(function($rootScope, $controller) {

        var scope = $rootScope.$new();

        BoardController = $controller('BoardController', { 
            $scope: scope,
            board: null,
            BoardService: null
        });

    }));


    it ("should toggle create_active", function() {
        var category = { create_active: false }

        BoardController.toggleCreateActive(category);

        expect(category.create_active).toBe(true);
    });

});

这是我要测试的功能:

    $scope.toggleCreateActive = function(category) {
        category.create_active = !category.create_active;
    }

我做错了什么?

【问题讨论】:

    标签: javascript angularjs unit-testing testing jasmine


    【解决方案1】:

    就像在最后一个清单中所说的,toggleCreateActive 是 $scope 上的一个函数。您不能将其引用为 BoardController.toggleCreateActive。而是让 scope var 可用于测试(将声明移出 beforeEach)并调用 scope.toggleCreateActive()。

    【讨论】:

      【解决方案2】:

      这应该可行:

      describe('BoardController', function() {
      
          beforeEach(module('examtesting'));
      
          var createController, scope;
      
          beforeEach(inject(function($rootScope, $controller) {
              scope = $rootScope.$new();
      
              createController = function() {
                  return $controller('BoardController', { 
                      $scope: scope,
                      board: null,
                      BoardService: null
                  });
              };
          }));
      
      
          it ("should toggle create_active", function() {
              var category = { create_active: false },
                  controller = createController();
      
              scope.toggleCreateActive(category);
      
              expect(category.create_active).toBe(true);
          });
      
      });
      

      【讨论】:

        【解决方案3】:

        当你使用 $scope 时,你所有的模型都在作用域上,而控制器只是控制器......

        使用 controllerAs 测试控制器

        在我们了解了如何测试服务之后,让我们来谈谈测试控制器。

        function MyController(MyService) {
         this.greetUpperCase = function(name) {
          return MyService.greet(name).toUpperCase();
         }
        }
        

        我们希望 Angular 的 DI 将我们的控制器实例注入到我们的测试中,但控制器不是作为服务的单例。

        因此,我们将:

        注入 $controller 服务 用它为我们实例化一个控制器

        var $controller;
        beforeEach(module('MyModule'));
        beforeEach(inject(function(_$controller_) {
            $controller = _$controller_; })
        );
        it('test greetUpperCase()', function() {
            var ctrl = $controller('MyController');
            expect(ctrl.greetUpperCase('bob')).toBe('HELLO BOB');
        });
        

        https://jsfiddle.net/ronapelbaum/tcmsw688/

        使用 $scope 测试控制器

        现在,如果您仍在使用 $scope:

        function MyController($scope, MyService) {
         $scope.greetUpperCase = function(name) {
          return MyService.greet(name).toUpperCase();
         }
        }
        

        基本上,当您使用 $scope 时,您并不真正关心控制器本身,因为它在其作用域上做所有事情。

        所以,我们需要:

        注入$rootScope 创建一个新范围 将其注入新控制器 测试 $scope

        it('test greetUpperCase()', function() {
         var myScope = $rootScope.$new();
         $controller('MyController', {
          $scope: myScope
         });
         expect(myScope .greetUpperCase('bob')).toBe('HELLO BOB');
        });
        

        https://jsfiddle.net/ronapelbaum/pkhaxmdg/

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多