2013-04-12 5 views
5

角度jsユニットテストでは、beforeEachメソッドではなく、各テスト(「it」メソッド内)にxhrレスポンスを設定する必要がありました。動作していない。?angular.js各テストでxhrリクエストを模擬する方法(またはスタブ)

これは

describe('ExampleListCtrl', function(){ 
    var $scope, $httpBackend; 

    beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) { 
    $httpBackend = _$httpBackend_; 
    $httpBackend.expectGET('examples').respond([]); // <--- THIS ONE 
    $controller(ExampleListCtrl, {$scope: $scope = $rootScope.$new()}); 
    })); 

    it('should create "examples" with 0 example fetched', function() { 
    expect($scope.examples).toBeUndefined(); 
    $httpBackend.flush(); 
    expect($scope.examples).toEqual([]); 
    }); 

}); 

結果

Executed 8 of 8 SUCCESS (0.366 secs/0.043 secs) 

に動作します。しかし、私は、各メソッドにメソッドをexpectGet移動したときに、これはエラーで失敗します。私は理由を知りません。

ここでは0
describe('ExampleListCtrl', function(){ 
    var $scope, $httpBackend; 

    beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) { 
    $httpBackend = _$httpBackend_; 
    $controller(ExampleListCtrl, {$scope: $scope = $rootScope.$new()}); 
    })); 

    it('should create "examples" with 0 example fetched', function() { 
    $httpBackend.expectGET('examples').respond([]); // <--- MOVED TO HERE 
    expect($scope.examples).toBeUndefined(); 
    $httpBackend.flush(); 
    expect($scope.examples).toEqual([]); 
    }); 
}); 

エラー

.... 
at /Users/me/app/test/unit/controllers/ExampleListCtrlSpec.js:3:1 
     Error: No pending request to flush 
at Error (<anonymous>) 
at Function.$httpBackend.flush (/Users/me/app/test/lib/angular/angular-mocks.js:1171:34) 
at null.<anonymous> (/Users/me/app/test/unit/controllers/ExampleListCtrlSpec.js:14:18) 

----編集----以下のアドバイスに従い

ですが、私は、beforeEachの外にコントローラを移動し、次のようにテストを変更しました私は$ httpBackend.expectGETを複数回テストすることができます。

describe('ExampleListCtrl', function(){ 
    var $scope, $rootScope, $httpBackend; 

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

    it('should create "examples" model with 0 example fetched from xhr', function() { 
    $httpBackend.expectGET('examples').respond([]); 
    controller(ExampleListCtrl, {$scope: $scope}); 
    $httpBackend.flush(); 
    expect($scope.examples).toEqual([]); 
    }); 

}); 

答えて

7

あなたのコントローラをインスタンス化したら、それは$httBackend、したがって、$httpをフェッチしているために起こります。したがって、それを要求する前にすべての期待がなされなければならない。

$httpBackend.expectGetを仕様(itブロック)に移動する場合は、期待通りに$controller(ExempleListCtrl, ...を移動する必要があります。

+1

@bighostkimコントローラの負荷に関するこれらの要求には問題があります。$ rootScopeに抽象化し、app.run()で初期化することを検討してください。 Caioが指摘したことからあなたのテストは失敗しています。 – Lucas

+0

そして、@ Lucasのアプローチに従えば、 '$ http'リクエストを発行するこのメソッドを呼び出す前に、必要に応じて期待通りに仕様に移動することができます。 @ルーカス、私は興味があります、あなたはどの問題について話していますか? –

+0

私は、コントローラーがロードされるたびに(たとえば、2つのコントローラー/ページの間をナビゲートする)、データをリフレッシュするたびにget要求を行うことについて話しています。私にとっては、これは悪いUXだと思った。リクエストをrootScopeまで移動することで、リクエストはアプリ起動時に1回だけ行われるので、コントローラ間をナビゲートするときにデータは更新されません。 – Lucas

関連する問題