code

AngularJs에서 개인 메서드를 사용하여 테스트 가능한 컨트롤러를 작성하는 방법은 무엇입니까?

starcafe 2023. 3. 9. 22:12
반응형

AngularJs에서 개인 메서드를 사용하여 테스트 가능한 컨트롤러를 작성하는 방법은 무엇입니까?

네, 그래서 저는 오랫동안 어떤 문제에 부딪혀왔기 때문에 다른 지역사회의 의견을 듣고 싶습니다.

먼저 추상 컨트롤러에 대해 살펴보겠습니다.

function Ctrl($scope, anyService) {

   $scope.field = "field";
   $scope.whenClicked = function() {
      util();
   };

   function util() {
      anyService.doSmth();
   }

}

분명히 다음과 같은 일이 있습니다.

  • 컨트롤러용 일반 발판$scope서비스 주입이 완료되었습니다.
  • 스코프에 부속된 몇 가지 필드 및 기능
  • 개인 방식util()

자, 이 수업을 유닛 테스트(재스민)에서 다루고 싶습니다.다만, (콜)을 클릭했을 때에, 확인하려고 하는 것이 문제입니다.whenClicked())의 몇 가지 아이템은util()메서드가 호출됩니다.어떻게 해야 할지 모르겠어요. 왜냐하면 재스민 테스트에서는 항상 오류가 나거든요.util()정의되지 않았거나 호출되지 않았습니다.

주의: 이 예를 수정하려는 것이 아니라 일반적인 코드 패턴 테스트에 대해 물어보는 것입니다.그러니 "정확한 오류"는 말하지 말아주세요.난 그걸 어떻게 하냐고 물어보는 거지, 이걸 어떻게 고치냐고 물어보는 게 아니야.

저는 이 문제를 해결하기 위해 여러 가지 방법을 시도해 왔습니다.

  • 분명히 나는 사용할 수 없다$scope이 오브젝트에 이 기능이 연결되어 있지 않기 때문에 유닛테스트에서 (보통 메시지로 끝납니다)Expected spy but got undefined또는 유사)
  • 이 기능을 컨트롤러 오브젝트에 연결하려고 했습니다.Ctrl.util = util;그런 다음 이런 모크들을 검증하고Ctrl.util = jasmine.createSpy()그러나 이 경우에는Ctrl.util호출되지 않기 때문에 테스트는 실패합니다.
  • 나는 변하려고 했다util()애착을 가지다this반대와 조롱Ctrl.util다시 말하지만, 운이 없다

글쎄요, 저는 이 문제를 해결할 방법을 찾을 수 없습니다. JS 닌자의 도움을 받을 수 있을 것 같습니다. 바이올린이 작동하면 완벽할 것 같습니다.

제공한 컨트롤러 함수는 Angular에 의해 생성자로 사용됩니다. 어느 시점에서 이 함수는 다음과 같이 호출됩니다.new실제 컨트롤러 인스턴스를 만듭니다.$scope에 노출되지 않지만 스파이/스텁/모킹에 사용할 수 있는 함수를 컨트롤러 오브젝트에 꼭 포함시켜야 할 경우 다음 URL에 첨부할 수 있습니다.this.

function Ctrl($scope, anyService) {

  $scope.field = "field";
  $scope.whenClicked = function() {
    util();
  };

  this.util = function() {
    anyService.doSmth();
  }
}

지금 전화할 때var ctrl = new Ctrl(...)또는 Angular를 사용합니다.$controller를 취득하기 위한 서비스Ctrl예를 들어 반환되는 오브젝트에는util기능.

다음 접근방식을 보실 수 있습니다.http://jsfiddle.net/yianisn/8P9Mv/

스코프에 이름을 붙이는 것은 공해입니다.이 논리를 다른 함수로 추출하여 컨트롤러에 주입합니다.

function Ctrl($scope, util) {

   $scope.field = "field";
   $scope.whenClicked = function() {
      util();
   };
}

angular.module("foo", [])
       .service("anyService", function(...){...})
       .factory("util", function(anyService) {
              return function() {
                     anyService.doSmth();
              };
       });

이제 Ctrl 및 "util"을 사용하여 유닛 테스트를 수행할 수 있습니다.

나는 다른 접근법으로 동참할 것이다.사적인 방법을 시험해 보면 안 돼그렇기 때문에 개인 사용자입니다.사용방법과 무관한 구현 세부 사항입니다.

예를 들어, util이 여러 곳에서 사용되었지만 다른 코드 리팩터링에 기반하여 이 한 곳에서만 호출된다는 것을 알게 되면 어떻게 될까요?왜추 기능 ?출 출? ???포함시키기만 하면 됩니다.anyService.doSmith() $scope.whenClicked()상기의 과 함께, 만약 여러분이 하고 있다고 한다면, 은 그것을 시험해 볼 수 있습니다.util()프로그램 기능을 변경하지 않아도 테스트가 중단됩니다.유닛 테스트의 주요 가치 중 하나는 물건을 망가뜨리지 않고 리팩터링을 단순화하는 것입니다.그래서 물건을 망가뜨리지 않았다면 테스트는 실패하지 않았을 것입니다.

할 은 '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때' '어느 때'를$scope.whenClicked라고 합니다.anyService.doSmth()고도불불 불불불다다필요한 것은 다음과 같습니다.

spyOn(anyService,'doSmith')
scope.whenClicked();
expect(anyService.doSmith).toHaveBeenCalled();

현재의 접근방식을 포함한 답변을 추가해, 코멘트를 얻고, 이것이 좋은 해결책인지 아닌지에 대해 논의를 진행시키고 싶다고 생각하고 있습니다.

컨트롤러 기능에 프라이빗 기능을 부가하고 있습니다(따라서 공개함으로써 모킹이 가능합니다). 구문을 " "를 만들고 .self컨트롤러 기능을 참조하는 객체. 이렇게 됩니다: ㄴ, ㄴ, ㄴ, ㄴ, ㄴ ㄴ이 되다.

function Ctrl($scope, anyService) {

   $scope.field = "field";
   $scope.whenClicked = function() {
      self.util();
   };

   var self = Ctrl; // For the sake of syntax simplicity only

   self.util = function() {
      anyService.doSmth();
   };

}

다음으로 유닛 테스트에서 다음을 사용할 수 있습니다.

Ctrl.util = jasmine.createSpy("util()");
expect(Ctrl.util).toHaveBeenCalled();

저는 여전히 이것이 별로 마음에 들지 않지만, 이것이 가장 간단한 방법이라고 생각합니다.누군가 더 나은 방법을 찾길 바란다.

언급URL : https://stackoverflow.com/questions/15966989/how-to-write-testable-controllers-with-private-methods-in-angularjs

반응형