programing

카르마 / 자스민으로 모달 인스턴스 컨트롤러를 테스트하는 장치

goodsources 2023. 9. 23. 22:32
반응형

카르마 / 자스민으로 모달 인스턴스 컨트롤러를 테스트하는 장치

EDIT : 이 게시물 끝에 있는 Quick & Dirty 솔루션

Angular의 modal window를 사용하고 있습니다.UI-Bootstrap은 파일을 분할한 것을 제외하고는 웹사이트에 설명된 것과 동일한 방식으로 이루어집니다.그러므로 나는 다음과 같습니다.

컨트롤러.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;

    });

그리고 카르마(carma 구성 파일에 ui-bootstrap-tpls.min.js 파일이 로드된 상태에서)로 이 코드를 테스트하면 다음 오류가 나타납니다. 오류(native): [$injector:unpr] [http://errors.angularjs.org/1.2.15-build.2389+sha.c5f2f58/$injector/unpr?p0=%24modalInstanceProvider%20%3C-%20%24modalInstance ]1. 이는 재스민이 $에 대한 공급자를 찾지 못함을 의미합니다.사례.

저는 아직 이 컨트롤러에서 테스트도 하지 않지만, 여기 제 재스민 테스트 파일이 있습니다.

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 () {

        });
    });

});

당신은 이 문제에 대해 어떤 단서라도 가지고 있습니까?제가 사용하는 (그리고 테스트하는) 첫 번째 "외부" 모듈이 아니며, 이번에는 작동하지 않고 왜 그런지 모르겠다는 점을 제외하고는 다른 모듈들과 동일한 작업을 했습니다.

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

편집: 빠르고 아마도 더러운 해결책:

자스민의 컨트롤러 인스턴스화에서 범위 조롱 방법을 바탕으로 문제를 "해결"할 수 있는 방법을 알아냈지만, 아마 꽤 지저분할 것입니다. 그러니 제가 의도한 대로 할 수 있는 더 나은 방법을 찾으시면 언제든지 의견을 내세요.

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 () {
        it('should instantiate the controller properly', function () {
            expect(Ctrl).not.toBeUndefined();
        });

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

        });
    });

});

이런 식으로 Jasmine은 공급자를 더 이상 검색하지 않습니다. 이미 공급자가 필요해야 할 항목을 주입했기 때문입니다.효과는 있지만 더 좋은 방법으로 할 수 있을 거라 믿습니다

나는 이것을 단지 모의를 만들어 내는 것으로 해결하고 있습니다.modal그리고.modalInstance객체들과 그것들이 내 컨트롤러 코드에 의해 호출되었다는 것을 확인합니다.부터modal그리고.modalInstance제3자 라이브러리의 일부이며, 해당 라이브러리가 제대로 작동하는지 테스트하는 것은 당사의 책임이 아니며, 라이브러리를 호출하는 코드가 정상적으로 작동하는지 테스트하는 것은 당사의 책임입니다.

예를 들어 다음과 같이 하십시오.

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,
        $modalInstance: modalInstance,
        itemArray: function () { return ['a', 'b', '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 객체에 의존할 필요가 없으며 장치 테스트는 훌륭하고 고립되어 있습니다.

대신:

modalInstance = {                    // Create a mock object using spies
  close: jasmine.createSpy('modalInstance.close'),
  dismiss: jasmine.createSpy('modalInstance.dismiss'),
  result: {
    then: jasmine.createSpy('modalInstance.result.then')
  }
};

다음과 같이 쓸 수 있습니다.

modalInstance = jasmine.createSpyObj('modalInstance', ['close', 'dismiss', 'result.then']);

또한 $modal이 없습니다.인스턴스는 이제 $uibModalInstance이므로 위의 모든 "modalInstance"는 "uibModalInstance"로 대체되어야 합니다.

피즈눌의 답은 +1.그것은 옳으며 선택되어야 합니다.

한 가지 주의하고 싶은 것은 여기에 제시된 방식으로는 유지보수가 불가능하다는 것입니다.

각도가 크기 때문에 사용하는 것을 추천합니다.

angular.module('...').service('$modalInstance', function(){
   ... define spies and such 
})

당신의 더 입니다 만 하면 됩니다. 아래에 파일을 추가하기만 하면 됩니다.spec에, 시키세요.karma.conf

하고 만 하면 됩니다.module동에서의 beforeEach

언급URL : https://stackoverflow.com/questions/22246813/unit-testing-a-modalinstance-controller-with-karma-jasmine

반응형