angularjs – 使用Karma/Jasmine单元测试模态控制器

前端之家收集整理的这篇文章主要介绍了angularjs – 使用Karma/Jasmine单元测试模态控制器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
编辑:快速&在这篇文章结尾的脏解决方

我使用AngularUI-Bootstrap中的模态窗口,与在网站上解释的相同的方式,除了我拆分文件
因此我有:

CallingController.js:

$scope.delete = function () {
    if ($scope.selected.length > 0) {
        // [...]
        // preparing data
        // [...]
        var modalInstance = $modal.open({
            templateUrl: 'views/modalView.html',controller: 'modalCtrl',resolve: {
                itemArray: function () {
                    return $scope.selected;
                }
            }
        });
        modalInstance.result.then(function (confirm) {
            if (confirm === true) {
                // [...]
                // treat
                // [...]
            }
        });
    }
};

modalController.js:

myAppControllers.controller('modalCtrl',function ($scope,$modalInstance,itemArray) {

        $scope.accept = function () {
            $modalInstance.close(true);
        };

        $scope.reject = function () {
            $modalInstance.close(false);
        };

        $scope.itemArray = itemArray;

    });

当我用Karma(在karma配置文件中加载ui-bootstrap-tpls.min.js文件)测试这个代码时,我得到以下错误
错误:[$ injector:unpr] [http://errors.angularjs.org/1.2.15-build.2389+sha.c5f2f58/ $ injector / unpr?p0 = $ modalInstanceProvider < - $ modalInstance] 1错误(本机),意味着jasmine不设法找到$ modalInstance的提供程序。

我甚至不测试这个控制器上的东西,还没有,但这里是我的茉莉花测试文件

testModalController.js:

describe('Controller: modalCtrl',function () {

    beforeEach(module('myApp'));

    var Ctrl;
    var scope;

    // Initialize the controller and a mock scope
    beforeEach(inject(
        function ($controller,$rootScope) {
            scope = $rootScope.$new();

            Ctrl = $controller('modalCtrl',{ $scope: scope });
        })
    );

    describe('Initial state',function () {
        it('should instantiate the controller properly',function () {
            expect(Ctrl).not.toBeUndefined();
        });

        it('should initialize its values properly',function () {

        });
    });

});

你有这个问题的任何线索吗?它不是我使用(和测试)的第一个“外部”模块,我做了相同的东西比其他人,除了这一次它不工作,我不知道为什么。

============================================

编辑:快速&大概脏的解决方案:

好吧,所以基于Jasmine控制器实例化的范围模拟方法,我想出了如何“解决”我的问题,但它可能很脏,所以随意评论,如果你找到一个更好的方式来做我想要的。

testModalController.js:

describe('Controller: modalCtrl',function () {

    beforeEach(module('myApp'));

    var Ctrl;
    var scope;
    var modalInstance;

    // Initialize the controller and a mock scope
    beforeEach(inject(
        function ($controller,$rootScope,_$modal_) {
            scope = $rootScope.$new();
            modalInstance = _$modal_.open({
                templateUrl: 'views/modalView.html'
            });

            Ctrl = $controller('modalCtrl',{
                $scope: scope,$modalInstance: modalInstance,itemArray: function () { return ['a','b','c']; }
            });
        })
    );

    describe('Initial state',function () {

        });
    });

});

这样,Jasmine不再搜索提供程序,因为您已经注入了应该需要这些提供程序的项目。它工作,但我相信它可以做一个更好的方式…

解决这个只是创建模拟模态和modalInstance对象,并验证他们已被我的控制器代码调用。因为modal和modalInstance是第三方库的一部分,所以测试它们是否正常工作不是我们的职责 – 而是我们的责任是测试我们调用库的代码是否正常工作。

使用您的示例:

describe('Controller: modalCtrl',function () {

  beforeEach(module('myApp'));

  var Ctrl;
  var scope;
  var modalInstance;

  // Initialize the controller and a mock scope
  beforeEach(inject(
    function ($controller,$rootScope) {     // Don't bother injecting a 'real' modal
      scope = $rootScope.$new();
      modalInstance = {                    // Create a mock object using spies
        close: jasmine.createSpy('modalInstance.close'),dismiss: jasmine.createSpy('modalInstance.dismiss'),result: {
          then: jasmine.createSpy('modalInstance.result.then')
        }
      };
      Ctrl = $controller('modalCtrl',{
        $scope: scope,'c']; }
      });
    })
  );

  describe('Initial state',function () {
    it('should instantiate the controller properly',function () {
      expect(Ctrl).not.toBeUndefined();
    });

    it('should close the modal with result "true" when accepted',function () {
      scope.accept();
      expect(modalInstance.close).toHaveBeenCalledWith(true);
    });

    it('should close the modal with result "false" when rejected',function () {
      scope.reject();
      expect(modalInstance.close).toHaveBeenCalledWith(false);
    });
  });
});

这样,我们真的不需要任何依赖于Angular-UI对象,我们的单元测试是好的和孤立的。

猜你在找的Angularjs相关文章