2013-03-20 5 views
7

나는 간단한 컨트롤러를 가지고 있으며, 내가 할 필요가있는 첫 번째 것은 값을 범위에 할당하는 것입니다.

function TestCtrl($scope, $http) { 
    $scope.listForms = 'some list'; 
} 

컨트롤러에 대한 다음 시험은 예상대로 작동합니다

describe('Testing a controller', function() { 

    var ctrl, scope, httpMock; 

    beforeEach(inject(function($injector) { 
     scope = $injector.get('$rootScope').$new(); 
     ctrl = $injector.get('$controller'); 
     ctrl(TestCtrl, { $scope: scope }); 
    })); 

    it("assigns to scope", function() { 
     expect(scope.listForms).toMatch("some list"); 
    }); 
}); 

을하지만 내 API

function TestCtrl($scope, $http) { 
    $http.get('/api/listForms').success(function(list) { 
    $scope.aListOfForms = 'some list'; 
    }); 
} 

에 테스트 변경에서 목록을 얻을 수있는 기능을 변경하는 경우
describe('Testing a controller', function() { 

    var ctrl, scope, httpMock; 

    beforeEach(inject(function($injector) { 
     httpMock = $injector.get('$httpBackend'); 

     scope = $injector.get('$rootScope').$new(); 
     httpMock.when('GET', '/tactical/api/listOrderForms').respond("an order form"); 

     ctrl = $injector.get('$controller'); 
     ctrl(TestCtrl, { 
      $scope: scope, 
      $http: httpMock 
     }); 
    })); 

    it("gets the list from the api and assigns it to scope", function() { 
     httpMock.expectGET('tactical/api/listOrderForms'); 
     expect(scope.orderFormList).toMatch("an order form"); 
     httpMock.flush(); 
    }); 
}); 

geg 다음 오류 :

TypeError: 'undefined' is not a function 
Expected undefined to match 'an order form'. 
Error: No pending request to flush ! 

내가 잘못하고있는 것을 아는 사람이 있습니까? 미리 감사드립니다.

답변

8

$ http는 외부 리소스와 통신하기 위해 $httpBackend을 사용합니다. 당신은 $httpBackend을 조롱했으나, 컨트롤러는 여전히 그 물결 $http 인터페이스와 이야기 할 필요가 있습니다.

이 그것을 수행해야합니다

describe('Testing a controller', function() { 

    var ctrl, scope, httpMock; 

    beforeEach(inject(function($controller, $rootScope, $httpBackend) { 
     httpMock = $httpBackend; 

     scope = $rootScope.$new(); 
     httpMock.when('GET', '/tactical/api/listOrderForms').respond("an order form"); 

     ctrl = $controller; 
     ctrl(TestCtrl, { 
      $scope: scope 
     }); 
    })); 

    it("gets the list from the api and assigns it to scope", function() { 
     httpMock.expectGET('tactical/api/listOrderForms'); 
     httpMock.flush(); 
     expect(scope.orderFormList).toMatch("an order form"); 
    }); 
}); 
+0

고마워요. 정말 도움이되었습니다. –

+0

그러나 $ httpBackend의 실제 구현을 수정 한 곳이 없습니다. 그렇다면 Angular는 실제 $ httpBackend 객체에있는 메소드를 호출하지 말고 $ http.get()이 호출 될 때 httpMock을 호출하는 것을 어떻게 알 수 있습니까? 나는 여기서 끔찍하게 혼란 스럽다. (Angular에 새로움) – Nikhil

+1

Nikhil, $ http는 $ http가 초기화 될 때 $ httpBack을 요구할 것이다. $ httpBackend는 싱글 톤 (하나의 인스턴스 만 존재)이며 httpMock은 그것에 대한 참조입니다. 테스트와 $ http 사이에서 공유되는이 $ httpBackend 인스턴스에서 콜백을 등록하고 작업을 수행하면이 작업이 가능합니다. –

0

expect() 전에 httpMock.flush()를 호출해야합니다. flush 호출은 http 요청에 바인딩 된 success 함수를 호출하는 "백엔드"에서 반환되는 응답을 시뮬레이트합니다.

+0

나는 (이) 있었다 플러시가 첫째가는 이유를 몰랐어요, 그래서 그것을 두 가지와 나는 여전히 같은 오류를 얻을 피곤 뭔가를 배웠습니다. –

3

컨트롤러의 $ httpBackend 서비스로 $ http service를 수동으로 대체 할 수 없습니다. 그것은 작동합니다

ctrl(TestCtrl, { 
     $scope: scope, 
     $http: httpMock 
    }); 

ctrl(TestCtrl, { 
     $scope: scope 
    }); 

변경합니다.

관련 문제