2016-03-28 14 views
1

私は内部のコールバックを持つコントローラを持っている:AngularJSでコントローラを約束した後、単体テストを行う方法は?

angular.module('controllers').controller('headerController', headerController); 

function headerController(headerService) { 
    var self = this; 

    headerService.getHeaderContentData() 
     .then(function(response) { 
      self.contentData = response.content; 
     }); 
} 

私の問題は、私はユニットテストでcontentDataの値をチェックする必要があるということです。私がexpect(ctrl.contentData).to.be.definedに電話をしたときに、そのテストに合格したのですが、ctrl.contentDataの値はundefinedです。この動作をテストする方法はありますか(コールバックが発生したときにself.contentDataをテストする)?

現在のユニットテスト:あなたのコントローラが$hhtpを使用していないので

describe("controller", function() { 
    var controller, $httpBackend; 

    beforeEach(angular.mock.inject(function($injector, _$httpBackend_){ 
     var $controller = $injector.get('$controller'); 
     $httpBackend = _$httpBackend_; 

     var $scope = {}; 
     $httpBackend.when('GET', '/data/header.content.json') 
        .respond(require('../../mock-data/header.content.json')); 
     var controller = $controller('headerController', { $scope: $scope }); 
     $httpBackend.flush(); 
    })); 

    it("should have contentData property populated", function() { 
     expect(controller.contentData).to.exist; // <- here fails: current value is undefined 
    }); 
}); 

私のユニットテストフレームワークは、ジャスミン

+0

を参照してください。コントローラを変更する必要がありますか? –

+0

'angular.mock.module( 'controllers')'おそらくこの行がありません! –

答えて

1

で、テストでそれを処理する理由はありません。 headerControllerをテストする適切な方法は、headerServiceを模擬することです。

モックサービス: - 使用$ qを

beforeEach(module(function($provide) { 
    mockService = jasmine.createSpyObj('headerService', ['getHeaderContentData']); 
    $provide.value('headerService', mockService); 
})); 

beforeEach(inject(function($controller) { 
    ctrl = $controller('headerController'); 
})); 

は今、あなたは約束を返すようにgetHeaderContentData()を模擬する必要があります。

モックサービス方法:

it('should change after promise resolved', inject(function($q, $rootScope) { 
    //create promise 
    deferred = $q.defer(); 

    //mock service response (foc controller's constructor) 
    mockService.getHeaderContentData.and.returnValue(deferred.promise); 

    //call init() 
    ctrl.init(); 

    expect(ctrl.contentData).toBeNull(); 

    deferred.resolve('Hello World'); 

    //not yet... 
    expect(ctrl.contentData).toBeNull(); 

    //from angular $q dosumentation: 
    //"it's important to know that the resolution of promises is tied to the digest cycle" 
    $rootScope.$apply(); 

    //now! 
    expect(ctrl.contentData).toBe('Hello World'); 

})); 

は、インスタンスが作成されたときにそれを呼び出してjsFiddle

+0

@ oscar.fimbres上記のすべてのことを行うことができ、約束を模擬するための同期プロミスライブラリを使用することでさらに簡単にすることができます。 'deferred.promise'の代わりに同期の約束を返して、望みのときに解決することができます。解決が終わったら、あなたは同期の問題で、ダイジェストサイクルのハッキングをしないで、すべての角度を確認できます。 [promise-sync](https://www.npmjs.com/package/promise-sync)ライブラリをご覧ください –

関連する問題