sourcecode

E2E 모의 $httpBackend 실제로 통과되지 않음나를 위해 관통합니다.

codebag 2023. 9. 25. 22:37
반응형

E2E 모의 $httpBackend 실제로 통과되지 않음나를 위해 관통합니다.

선택한 요청을 서버에 전달하기 위해 $httpBackend를 설정하는 방법에 대해 여기에 나와 있는 지침을 따르고 있다고 생각하지만, 저는 이 방법이 작동하지 않습니다.

여기 제가 무엇을 하고 있는지 보여주고 무엇이 잘못되고 있는 것처럼 보이는지 댓글로 설명하는 불합격 테스트있는 Plunkr이 있습니다.

어떤 그 $httpBackend 있지 $httpBackend XHR면인다에게 $httpBackend대신.해야 할지 .두 번째 호출에서는 요청을 어떻게 처리해야 할지 모르기 때문에 예외가 발생합니다.

data encouncement에 대한 대응

중간 테스트에 대한 당신의 글을 감사히 기억합니다.단위 테스트와 E2E 테스트 사이에 포함되는 중요한 통합 테스트 범위를 식별합니다.저는 그 중간 지대에 서 있습니다.

저는 당신이 까불고 있다고 전혀 생각하지 않습니다.당신의 대답은 지극히 합리적입니다...또는 "API reference / ngMockE2E / $httpBackend" 텍스트와 모순되지 않는 것이 타당입니다.인용하자면:

은 또는 하는 데 될 수 .when 및 그 api기(whenGET,whenPOST, 선택적으로 특정 요청(예: 특정 원격 아피스와 상호 작용하거나 웹 서버에서 템플릿을 가져오는 것)에 대한 요청을 real로 전달합니다.

[I]엔드 투 엔드 테스트 시나리오 또는 실제 백엔드 api를 모의로 대체하여 응용 프로그램을 개발할 때 특정 범주의 요청은 모의를 무시하고 실제 http 요청발행하는 것이 종종 바람직합니다.이 동작으로 백엔드를 구성하려면passThrough합니다가(가) 아닌 합니다.respond[내 강조]

는 E2E E2E 는 하고 있습니다.$httpBackend재스민 환경에서의 사용.나는 그것을 배제할 이유가 생각나지 않습니다.만약 그런 이유가 있다면 그들은 그것을 분명히 말해야 합니다.정말로, 누가 모의 구성 요소에 대해 읽고 시험 환경에서 그것을 사용할 것이라고 예상하지 않습니까?

"특정 원격 아피스와 상호 작용하는 것과 같은 특정 요청에 대한 요청을 실제에게 전달하는 것"이 바로 제가 의도하는 바입니다.해당 구성 요소의 비모의 버전을 제외하고 "진짜 $httpBackend"는 무엇을 의미할 수 있습니까?

나는 당신의 주장을 이해할 수 없습니다.

ngMocksE2E모듈은 실제 각도 응용 프로그램이 실행되는 "서버" 쪽에서 사용하도록 설계되었습니다.

"server"라는 단어는 해당 페이지에 정확히 세 번 나타나지만, 애플리케이션 코드가 "server"에서 실행된다는 것을 암시하는 것은 아닙니다.사물의 '서버' 쪽에서 실행되는 '실제 각도 애플리케이션'이 무슨 뜻인지 모르겠습니다.

는 E2E 합니다.$httpBackendE2E 테스트에만 국한되지 않습니다.또한 "실제 백엔드 api를 모의로 대체하여 애플리케이션을 개발하는 경우"를 위한 것입니다.

이는 실제 백엔드 API사용하여 애플리케이션을 테스트하는 시나리오에서 불과 반 정도 떨어진 것입니다."

제 시나리오에서는 SUT가 서버에서 데이터를 가져오는 구성 요소를 호출합니다.내 테스트는 이 종속 구성 요소가 실제 백엔드의 요청에 성공하고 예상되는 방식으로 데이터를 검색하거나 저장하는지 확인하기 위해 존재합니다.이것은 백엔드의 동작을 조롱하여 적절하게 만족시킬 수 없는 통합 테스트입니다.

물론 저는 모의 XHR 응답을 통해 백엔드의 동작이 될 것으로 예상되는 것에 대해 구성 요소가 적절하게 반응하는 능력을 테스트(그리고 테스트).이는 구성 요소가 실제 백엔드 동작에 적절하게 반응하는지 확인하는 것과 같지 않습니다.애플리케이션이 진화함에 따라 변화할 수 있으며 조롱된 응답에서 상당한 방식으로 벗어날 수 있습니다.

이를 위해 SUT의 코드 경로로 바꾸는 방법을 이해했다면 당신의 미드웨이 테스터를 사용하는 것을 고려하고 싶습니다.없어. 을 하는 이 당신의 XHR 요청을 하는 컴포넌트는 당신의 접근이 불가능하다고 생각합니다에 접근할 수 없는 것 .ngMidwayTester 도우미를 있습니다 하지만 필요하다면 XHR 도우미를 파이프라인에 쑤셔넣을 방법은 알고 있습니다.

지금 제가 서 있는 곳이 여기입니다.

가 수 ,$httpBackend에 명시된 그렇지 않으면합니다 -입니다 -합니다.passThrough작업 중인 XHR 구현으로 나 자신을 구현할 수 있습니다.

저는 첫번째 옵션이 더 좋습니다.만약 두 번째로 이동한다면, 저는 저의 요구와 API 문서에 대한 저의 해석을 공유하는 다른 사람들의 이익을 위해 여기에 링크를 제공할 것입니다.

제가 놓치는 제3의 길이 있습니까?

나는 같은 문제를 우연히 발견했지만 풍부한 API를 구현하거나 기존의 각진 조롱을 대체하는 대신 다음과 같은 도움말에서 간단히 추가되었습니다.

angular.module('httpReal', ['ng'])
    .config(['$provide', function($provide) {
        $provide.decorator('$httpBackend', function() {
            return angular.injector(['ng']).get('$httpBackend');
        });
    }])
    .service('httpReal', ['$rootScope', function($rootScope) {
        this.submit = function() {
            $rootScope.$digest();
        };
    }]);

HTTP 요청이 전달되지 못하게 하는 두 가지 문제를 패치합니다.

  1. 의 를 복원합니다.$httpBackend;

  2. 요청을 수행할 수 있는 방법을 제공합니다. 그렇지 않으면 Angular에 있을 것입니다.JS의 대기열이 다이제스트 루프를 기다리고 있습니다.

describe('my service', function() {
    var myService, httpReal;

    beforeEach(module('myModule', 'httpReal'));

    beforeEach(inject(function( _myService_, _httpReal_ ) {
        myService = _myService_;
        httpReal = _httpReal_;
    }));

    it('should return valid data', function(done) {
        myService.remoteCall().then(
            function(data) {
                expect(data).toBeDefined();
                done();
            }, function(error) {
                expect(false).toBeTruthy();
                done();
            });

        httpReal.submit();
    });
});

은 입니다.$httpBackend은 안에 .ngMockE2E모듈.

ngMockE2E모듈은 단순히 재스민 사양 내에서 설계되거나 사용되지 않습니다.

엔드 투 엔드 테스트를 수행할 때 테스트에는 두 가지 측면이 있습니다.하나는 테스트 중인 각도 응용 프로그램이고, 다른 하나는 Jasmine 사양에 있는 각도 시나리오 코드입니다.

E2E 테스트에서는 재스민 측면(시나리오 런너 제외)에 각도 모듈이나 ng-mock 또는 각도 관련된 것이 없습니다.

ngMocksE2E모듈은 실제 각도 응용 프로그램이 실행되는 "서버" 쪽에서 사용하도록 설계되었습니다.각 .의 JSON가 UI입니다를 보다 통합 가 훨씬 될 수 캔을 할 수 하는

ng-mocks.,angular 는 $httpBackend 를로 합니다.ngMocksE2E은 "은 짜"다를 수 .$httpBackend이미 아셨듯이, 모의고사를 포장하고 패스스루에 위임하겠습니다.

당신이 작성하려는 테스트의 종류는 UI 통합을 테스트하는 것이 아니라 어플리케이션 자바스크립트와 서버 통합을 테스트하는 테스트인 것 같습니다.

이것은 완벽하게 합법적인 테스트 스타일입니다(일부에서는 '중간'이라고도 함).각진 공동체에서 '테스트'(testing).당신의 문제는 당신이 잘못된 도구를 사용하고 있다는 것입니다.

이것을 보고 싶습니다.

https://github.com/yearofmoo/ngMidwayTester

각모의와 각.module()을 사용하지 않고 테스트를 수행할 수 있습니다.

자세한 내용은 여기에서 확인할 수 있습니다.

http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html

(이미 연결되어 있는 경우 apologies)

편집: (문제의 추가 의견을 해결하기 위해)

에 대한 을 품고 있습니다.ngMockE2E엔드 투 엔드 테스트 설정의 클라이언트(예: 카르마/jasmine) 측에서는 사용할 수 없습니다.자기가 해석한 것처럼 해석하는 것이 무리는 아니지만, 해석이 틀렸다는 사실을 바꾸지는 않습니다.

ngMockE2E는 클라이언트 측이 아닌 애플리케이션의 서버 측에서 사용할 때 지시가 있으면 요청을 전달합니다.이는 사용자가 사전 검색된 응답으로 조롱하기 어려운 특정 요청을 여전히 전달할 수 있도록 하는 것을 의미합니다.클라이언트와 서버 측에서 의미하는 것은 엔드 투 엔드 테스트에는 두 가지 목적이 있다는 것입니다.표준 응용 프로그램 서버에서 제공되는 테스트 대상 응용 프로그램이 있고, 카르마 또는 다른 테스트 런너에서 일반적으로 실행되는 응용 프로그램을 구동하는 테스트 코드가 있으며, 이는 표준 HTTP 요청을 사용하여 다른 프로세스에서 실행되는 응용 프로그램과 통신합니다.

다음과 같습니다.ngMockE2EJasmine에 대한 언급이 없으며 실제 각도 애플리케이션에서 설정하는 방법에 대한 지침이 있습니다.

myAppDev = angular.module('myAppDev', ['myApp', 'ngMockE2E']);
myAppDev.run(function($httpBackend) {
  phones = [{name: 'phone1'}, {name: 'phone2'}];

  // returns the current list of phones
  $httpBackend.whenGET('/phones').respond(phones);

  // adds a new phone to the phones array
  $httpBackend.whenPOST('/phones').respond(function(method, url, data) {
    phones.push(angular.fromJson(data));
  });
  $httpBackend.whenGET(/^\/templates\//).passThrough();
  //...
});

이 예에서 볼 수 있듯이 JSON 데이터 명령을 모두 조롱하면서 서버에서 템플릿을 가져오도록 합니다.

입니다를 이 상당히 입니다.angular.mock.module('ngMockE2E')하는 거죠$httpBackend.whenGET()일순간에beforeEach()module.run().

ngMidwayTester제가 당신을 연결시켰는데, 사실은 이것이 당신과 양립할 수 있을 것이라고 생각합니다.ngMockE2E으로.ngMidwayTester하다, 갈음하다.angular.mock.module()그리고.inject()자체적인 구현을 통해서 말입니다.이렇게 사용할 수 있습니다.

beforeEach(function(){
  tester = ngMidwayTester('app', 'ngMockE2E');
  $http = tester.inject('$http');
  $httpBackend = tester.inject('$httpBackend');
  $rootScope = tester.inject('$rootScope');
});

(ngMock (됨)을 할 때 을 더 이 .angular.mock.module() 를 .ngMidwayTester.

실제 백엔드 호출로 앱을 테스트하기 위해 수정된 버전을 사용했습니다.

재스민의 단위 테스트와 마찬가지로 작동합니다.

Jasmine 2.0과 함께 사용하고 있으므로 테스트는 다음과 같습니다.

it(' myTest', function (done) {
    _myService.apiCall()
        .then(function () {
            expect(true).toBeTruthy();
            done()
        });
});

: done비동기 호출 때문에 필요합니다.

ngMock을 유닛 테스트에 사용할 때 실제 HTTP 통화를 할 때 사용하는 솔루션입니다.주로 디버깅, API 시용, JSON 예제 얻기 등에 사용합니다.

블로그에 솔루션에 대한 보다 자세한 게시물을 작성했습니다.ngMockE2E & pass를 이용한 실제 HTTP 통화로 Unit Test하는 방법관통.

해결책은 다음과 같습니다.

angular.mock.http = {};

angular.mock.http.init = function() {

  angular.module('ngMock', ['ng', 'ngMockE2E']).provider({
    $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
    $log: angular.mock.$LogProvider,
    $interval: angular.mock.$IntervalProvider,
    $rootElement: angular.mock.$RootElementProvider
  }).config(['$provide', function($provide) {
    $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
    $provide.decorator('$$rAF', angular.mock.$RAFDecorator);
    $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
    $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
    $provide.decorator('$controller', angular.mock.$ControllerDecorator);
  }]);

};

angular.mock.http.reset = function() {

  angular.module('ngMock', ['ng']).provider({
    $browser: angular.mock.$BrowserProvider,
    $exceptionHandler: angular.mock.$ExceptionHandlerProvider,
    $log: angular.mock.$LogProvider,
    $interval: angular.mock.$IntervalProvider,
    $httpBackend: angular.mock.$HttpBackendProvider,
    $rootElement: angular.mock.$RootElementProvider
  }).config(['$provide', function($provide) {
    $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
    $provide.decorator('$$rAF', angular.mock.$RAFDecorator);
    $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
    $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
    $provide.decorator('$controller', angular.mock.$ControllerDecorator);
  }]);

};

ngMock 다음에 이 소스 파일을 포함합니다. 예:

<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="angular-mocks.js"></script>
<!-- this would be the source code just provided -->
<script type="text/javascript" src="ngMockHttp.js"></script>

시험은 어떻게 작성해야 합니까?

  describe('http tests', function () {

    beforeEach(module('moviesApp'));

    var $controller;
    var $httpBackend;
    var $scope;

    describe('real http tests', function() {

      beforeEach(angular.mock.http.init);
      afterEach(angular.mock.http.reset);

      beforeEach(inject(function(_$controller_, _$httpBackend_) {
        $controller = _$controller_;
        $scope = {};
        $httpBackend = _$httpBackend_;

        // Note that this HTTP backend is ngMockE2E's, and will make a real HTTP request
        $httpBackend.whenGET('http://www.omdbapi.com/?s=terminator').passThrough();
      }));

      it('should load default movies (with real http request)', function (done) {
        var moviesController = $controller('MovieController', { $scope: $scope });

        setTimeout(function() {
          expect($scope.movies).not.toEqual([]);
          done();
        }, 1000);

      });

    });

  });

어떻게 돼가요?

그것은 ngMockE2E 버전의 $httpBackEndProvider를 사용하며, 우리에게 패스를 제공합니다.기능을 통해 테스트에 사용되고 있음을 알 수 있습니다.이렇게 하면 이름에서 제안하는 대로 수행되며 네이티브 HTTP 호출을 통과할 수 있습니다.

$BrowserProvider의 가짜 버전 없이 ngMock 모듈을 다시 정의해야 합니다. ngMock을 사용하는 단위 테스트에서 실제 HTTP 호출을 방지하기 때문입니다.

왜 이런 식으로 하는 거지?

테스트를 작성할 때 워크플로우에 도움이 되기 때문에 가짜와 실제 HTTP 호출을 쉽게 전환할 수 있는 유연성이 좋습니다. 그래서 ngMockE2E의 $httpBackEndProvider 버전이 사용됩니다.또한 ngMock을 사용하는 것과 동일한 방식으로 유닛 테스트를 코딩할 수 있습니다. 여기서 각 라인 앞/뒤에 간단히 들르거나 빼서 angular.mock.http.init/reset을 등록할 수 있습니다.

플렁크르

예를 들어 플렁커(Plunkr)를 소개합니다.

언급URL : https://stackoverflow.com/questions/20864764/e2e-mock-httpbackend-doesnt-actually-passthrough-for-me

반응형