2016-06-07 3 views
2

그래서 GET 호출에서 서비스에서 json을 되찾기 위해 우리가 통제 할 수없는 "안절부절 한"서비스를 사용해야하는 상황이있었습니다. Content-Type = "application/json"헤더에 있습니다. 문제는 Angular가 GET의 요청 헤더에서 Content-Type을 제거한다는 것입니다. 나는 우리가 그것을 전송하기 전에 전화를 차단하고 콘텐츠 유형 다시 추가 할 수 있습니다 $ httpBackend에 장식하여 제안 된 블로그 게시물을 발견 : 그래서

angular 
.module('MyApp') 
.decorator('$httpBackend', [ 
    '$delegate', function($delegate) { 
     return function() { 
      var contentType, headers; 
      headers = arguments[4]; 
      contentType = headers != null ? headers['X-Force-Content-Type'] : null; 
      if (contentType != null && headers['Content-Type'] == null) 
      headers['Content-Type'] = contentType; 

      return $delegate.apply(null, arguments); 
     }; 
    }]); 

, 즉 아름답게 작품! 이제 문제는 우리가 모의 $ httpBackend 서비스를 사용하는 모든 유닛 테스트를 망가 뜨렸다는 것입니다. 우리가 얻는 유일한 오류는 "undefined"입니다.

Ex. 단위 테스트 방법 :

it('should return service.model.error if service returns an exception code from EndProject', 
inject(function($httpBackend) { 
     var mockResponse = sinon.stub({ 'exception': 'Unable to retrieve service data' }); 
     $httpBackend.whenPUT(this.endProjectUrl).respond(mockResponse); 
     var data; 
     this.service.EndProject().then(function(fetchedData) { 
      data = fetchedData; 
     }); 

     $httpBackend.flush(); 
     expect(data.error.state).toBe(true); 
     expect(data.error.message).toEqual('Unable to retrieve service data'); 
})); 

PhantomJS 2.1.1 (맥 OS X 0.0.0) projectService EndProject 서비스가 정의되지 않은 /사용자/mlm1205을 실패 EndProject에서 예외 코드를 반환하는 경우 service.model.error를 반환해야 /Documents/THDSource/bolt-projects/html_app/src/app/components/services/project/projectService.spec.js:213:41 @/Users/mlm1205/Documents/THDSource/bolt-projects/html_app/bower_components/angular/angular.js : 4560 : 22 [email protected]/Users/mlm1205/Documents/THDSource/bolt-projects/html_app/bower_components/angular-mocks/angular-mocks.js : 2518 : 26

답변

0

궁극적으로 내 질문에 대한 답변으로 estus의 대답을 표시했지만 궁극적으로 우리가 함께가는 최종 결과는 아닙니다. 나무를 통해 숲이 보이지 않는 경우, 가장 간단한 해결책은 빈 데이터 요소를 $ http 호출의 config에 추가하는 것입니다.이전에 시도해 보았지만 작동하지 않았습니다 (또는 그렇게 보였습니다).하지만 다시 작업 한 후에 실제로 작동했기 때문에 응용 프로그램에서 데코레이터를 제거 할 수있었습니다.

return $http.get(getItemInformationUrl + params, { dataType: 'json', data: '', headers: {'Content-Type': 'application/json'} }).then(getItemInformationCompleted).catch(getItemInformationFailed); 
1

나열된 데코레이터는 패치 된 함수가 생성자가 아니며 정적 속성 및 메서드가없는 단순한 원숭이 패치 시나리오를 다룹니다.

이것은 $httpBackend in ng module에 해당하며 추가 기능이없는 공장 기능입니다.

ngMockE2E 모듈이 $httpBackend을 덮어 쓰고 정적 방법이 at least some of them are documented 인 모듈에는이 내용이 적용되지 않습니다.

이것은 원숭이 패치

app.decorator('$httpBackend', ['$delegate', function ($delegate) { 
    var $httpBackend = function() { 
     ... 
     return $delegate.apply(null, arguments); 
    }; 
    angular.extend($httpBackend, $delegate); 
    return $httpBackend; 
}]); 

관계없이 그 공장 기능을하고, 모듈화 좋은 습관에 대해 일반적으로 안전 레시피 (이것은 비 열거 및 상속 속성을 포함하지 않음)을 의미 (이 문제는 이것이 중요한 이유의 표현적인 예입니다). 등 app.unitA은 (app.common에서로드 부 실험에 별도로 장착 될 수 있음), app.common (공통 분모) (E2E 테스트에서 부트 스트래핑) (제조에서 부트 스트래핑) app.e2eapp이 편리하다

애플리케이션의 대부분 전체 코드 (configrun 블록, 라우팅)는 별도의 모듈로 이동하여 해당 모듈에 직접 의존하는 모듈에만로드 할 수 있습니다. 이것이 decorator 유닛 자체를 테스트하는 스펙이 아니라면 데코레이터 모듈을로드해서는 안됩니다.

사양 오류를 디버깅 할 때 PhantomJS보다 Chrome may offer superior experience이 표시됩니다.

+0

나는 그것을 시도했지만 Content-Type이 제거 된 통화는 계속 진행 중이다. 로드 밸런서가 필요로하는 또 다른 헤더를 삽입하는 인터셉터가 있는데, Content-Type을 시도했지만 작동하지 않았습니다. 인터셉터 코드를 통해 디버그하고 실제로 헤더를 추가하는지 확인하지만 Network 탭 (Chrome 개발자 도구)에서 실제 호출을 보면 Content-Type 헤더가 사라집니다. – Shaggy13spe

+0

전에 사건을 잘못 해석 한 것 같습니다. 단위 테스트가 실제 요청을하지 않는다는 사실에도 불구하고 당신을 위해 작동하지만 단위 테스트에는 실패한 프로덕션 용 데코레이터가 있습니다. 답변을 업데이트했습니다. PhantomJS에 대한 주석을 보면, 나는 그 때문에 오류 메시지가 절름발이이며'$ httpBackend.whenPUT (...) '때문에'undefined is a function이 아닌 것'과 같은 말을해야한다. – estus

+0

예, 미안해 내가 분명히하지 않았다면. 나는 당신이 제안한 것과 조금 놀아 보려고 노력할 것이다. 저는 GET 요청에 헤더를 요구하는 것은 우스꽝 스럽기 때문에 실제로 서비스를 변경 한 팀으로 되돌아 가려고합니다. – Shaggy13spe