0

私は単位テストをしたい非常に基本的な工場サービスを持っています。私はexpectステートメントの前に$rootScope.$digest()$rootScope.$apply()を試していますが、ユニットテストで成功ハンドラーか失敗ハンドラーのいずれも呼び出されていません。しかし、このファクトリーを使用しているコントローラーのコンテキストではアプリケーションで問題なく呼び出されます。

example.service.js:

(function (angular) { 
    'use strict'; 

    angular 
    .module('exampleModule') 
    .factory('ExampleApi', ExampleApi); 

    ExampleApi.$inject = ['$http']; 
    function ExampleApi($http) { 
    return { 
     get: getExampleData 
    } 

    function getExampleData() { 
     return $http.get('example-endpoint'); 
    } 
    } 

})(angular); 

example.service.spec.js

'use strict'; 

describe('Example API service', function() { 
    var $httpBackend; 
    var $rootScope; 
    var ExampleApi; 

    beforeEach(module('exampleModule')); 

    beforeEach(inject(
    function(_$httpBackend_, _$rootScope_, _ExampleApi_) { 
     $httpBackend = _$httpBackend_; 
     $rootScope = _$rootScope_; 
     ExampleApi = _ExampleApi_; 
    })); 

    it('calls the success handler on success', function() { 
    $httpBackend 
     .expectGET('example-endpoint') 
     .respond(200); 

    var handlerStubs = { 
     success: function() { 
     console.log("success called"); 
     }, 
     failure: function() { 
     console.log("failure called"); 
     } 
    } 

    spyOn(handlerStubs, 'success').and.callThrough(); 
    spyOn(handlerStubs, 'failure').and.callThrough(); 
    ExampleApi.get().then(handlerStubs.success, handlerStubs.failure); 
    //$rootScope.$digest(); 
    $rootScope.$apply(); 
    expect(handlerStubs.failure.calls.count()).toEqual(0); 
    expect(handlerStubs.success.calls.count()).toEqual(1); 
    }); 
}); 
+3

;'試みる '$ httpBackend.flush();これは、右の応答(200)' '後に動作しますが、それはなかった@LukeHutton' –

+0

'ExampleApi.get()'ステートメントの後のDID。それを答えとして書くなら、それを正しいものとしてマークします。どうもありがとうございました! ( 'response'行の後に、' Error:フラッシュする要求がありません! 'というエラーが出ました。これが 'get()'の後で試してみた理由です)。 – anjunatl

答えて

1

$httpBackendモックが呼び出されたときには、getを解決しますflush()方法を含み、リクエストを使用して、テスト対象コードの同期制御を行います。 $httpBackend.flush();が呼び出されると、期待値.expectGETが確認されます。

From the Angular Docs:応答(200) `後

The $httpBackend used in production always responds to requests asynchronously. If we preserved this behavior in unit testing, we'd have to create async unit tests, which are hard to write, to follow and to maintain. But neither can the testing mock respond synchronously; that would change the execution of the code under test. For this reason, the mock $httpBackend has a flush() method, which allows the test to explicitly flush pending requests. This preserves the async api of the backend, while allowing the test to execute synchronously.

関連する問題