programing

UI 라우터가 $httpbackend 유닛 테스트, angular js와 간섭합니다.

fastcode 2023. 3. 11. 09:36
반응형

UI 라우터가 $httpbackend 유닛 테스트, angular js와 간섭합니다.

송신 기능이 있는 컨트롤러는 다음과 같습니다.

$scope.submit = function(){   

 $http.post('/api/project', $scope.project)
      .success(function(data, status){
        $modalInstance.dismiss(true);
      })
      .error(function(data){
        console.log(data);
      })
  }
}

이건 내 시험이야

it('should make a post to /api/project on submit and close the modal on success', function() {
    scope.submit();

    $httpBackend.expectPOST('/api/project').respond(200, 'test');

    $httpBackend.flush();

    expect(modalInstance.dismiss).toHaveBeenCalledWith(true);
  });

표시되는 에러는 다음과 같습니다.

Error: Unexpected request: GET views/appBar.html

views/appBar.html은 my templateUrl:

 .state('project', {
    url: '/',
    templateUrl:'views/appBar.html',
    controller: 'ProjectsCtrl'
  })

그래서 왠지 ui-router가 전송함수가 아닌 $httpBackend를 이 포인트로 만들고 있습니다.$httpBackend를 사용한 모든 테스트에서 동일한 문제가 발생합니다.

이에 대한 해결책이 있습니까?

다음 요지를 참고하세요.https://gist.github.com/wilsonwc/8358542

angular.module('stateMock',[]);
angular.module('stateMock').service("$state", function($q){
    this.expectedTransitions = [];
    this.transitionTo = function(stateName){
        if(this.expectedTransitions.length > 0){
            var expectedState = this.expectedTransitions.shift();
            if(expectedState !== stateName){
                throw Error("Expected transition to state: " + expectedState + " but transitioned to " + stateName );
            }
        }else{
            throw Error("No more transitions were expected! Tried to transition to "+ stateName );
        }
        console.log("Mock transition to: " + stateName);
        var deferred = $q.defer();
        var promise = deferred.promise;
        deferred.resolve();
        return promise;
    }
    this.go = this.transitionTo;
    this.expectTransitionTo = function(stateName){
        this.expectedTransitions.push(stateName);
    }

    this.ensureAllTransitionsHappened = function(){
        if(this.expectedTransitions.length > 0){
            throw Error("Not all transitions happened!");
        }
    }
});

테스트/모크 폴더에 있는 stateMock이라는 파일에 파일을 추가하고 아직 픽업되지 않은 경우 해당 파일을 카르마 구성에 포함합니다.

테스트 전 설정은 다음과 같습니다.

beforeEach(module('stateMock'));

// Initialize the controller and a mock scope
beforeEach(inject(function ($state //other vars as needed) {
    state = $state;
    //initialize other stuff
}

그런 다음 테스트에서 다음을 추가해야 합니다.

state.expectTransitionTo('project');

유닛 테스트 UI 라우터에 관한 이 Github 문제에서는 어떤 일이 일어나고 있는지 자세히 설명합니다.

문제는 말이다$httpBackend.flush()브로드캐스트를 트리거하고, 그 이외의 경우는stateProvider.

간단한 해결책은 위에서 설명한 Github 스레드의 @darinclark에서 설명한 바와 같이 다음과 같은 설정을 수행하는 것입니다.이는 상태 천이를 테스트할 필요가 없는 경우에 유효합니다.아니면 @Vratislav의 Github에 대한 답변에서 영감을 얻은 @rosswil의 답변을 보십시오.

beforeEach(module(function ($urlRouterProvider) {
    $urlRouterProvider.otherwise(function(){return false;});
}));

편집필

Chris T가 코멘트로 보고한 덕분에 v0.2.14 이후인 것 같습니다.이것에 가장 좋은 방법은

beforeEach(module(function($urlRouterProvider) {
  $urlRouterProvider.deferIntercept();
}));

올바른 솔루션에 기재되어 있는 gist 파일을 추가하지 않으면 $httpBackend에 "when" 조건을 추가하여 다음과 같은 뷰의 GET 청원을 무시할 수 있습니다.

$httpBackend.when("GET", function (url) {
    // This condition works for my needs, but maybe you need to improve it
    return url.indexOf(".tpl.html") !== -1;
}).passThrough();

고객님께서 지적하신 것과 동일한 오류가 있습니다.콜 서비스 후 다른 ui-route의 URL에 대해 문의합니다.

콜 문제를 해결하기 위해 테스트에서 그렇지 않은 경우 ui-route는 beforeach 스테이트먼트에 $state를 삽입하지 않습니다.제 테스트에서는 $state는 그것을 사용하는 센스가 없습니다.

서비스를 ui.router에 의존하지 않는 자체 모듈로 이동합니다.이 모듈에 따라 메인 앱이 달라집니다.메인 앱을 테스트하지 않을 때는 서비스가 포함된 모듈을 테스트합니다.이 모듈은 ui.router에 대해 아무것도 모르기 때문에 상태 제공자는 상태/경로를 변경하려고 하지 않습니다.이건 나한테 효과가 있었어.

언급URL : https://stackoverflow.com/questions/23655307/ui-router-interfers-with-httpbackend-unit-test-angular-js

반응형