2016-06-16 24 views
0

私はカルマ+ジャスミンを使って角型プロジェクトの単体テストを書く。約束を返すテストアングルサービス

私は、約束により正しい結果を返すAngularサービスをテストしようとしています。以下は私がこれまで持っていたものです。

プロジェクトサービスkarma startを実行

'use strict'; 
 

 
var app = app || {}; 
 

 
app.factory('ProjectSvc', ['$http', '$q', function($http, $q) { 
 

 
    var project_url = 'https://dl.dropboxusercontent.com/u/2122820/hosted_json/project.json'; 
 

 
    var svc = {}; 
 
    svc.cachedProjects = []; 
 

 
    svc.getProjects = function() { 
 
     return $http.get(project_url); 
 
    } 
 

 
    function lookUp(slug) { 
 
     for (var i=0; i < svc.cachedProjects.length; i++){ 
 
      if (svc.cachedProjects[i].slug && svc.cachedProjects[i].slug == slug) { 
 
       return svc.cachedProjects[i]; 
 
      } else if (svc.cachedProjects[i].title == slug) { 
 
       return svc.cachedProjects[i]; 
 
      
 
      } 
 
     } 
 
     return null; 
 
    } 
 

 
    //return a promise 
 
    svc.retrieveProjectById = function(id) { 
 
     var deferred = $q.defer(); 
 
     if (svc.cachedProjects.length > 0) {  
 
      var found = lookUp(id); 
 
       if (!found) { 
 
        deferred.reject ({error: 'not found', data: null}); 
 
       } else { 
 
        deferred.resolve(found); 
 
       } 
 
     } else { 
 
      init().then(function(data){ 
 
       //console.log('---------'); 
 
       svc.cachedProjects = data.data.projects; 
 

 
       var found = lookUp(id); 
 
       //console.log('found: ', found); 
 
       if (!found) { 
 
        deferred.reject ({error: 'not found', data: null}); 
 
       } else { 
 
        deferred.resolve(found); 
 
       } 
 
      }) 
 
     } 
 
     return deferred.promise; 
 
    } 
 

 
    //return a promise 
 
    svc.retrieveProjectBySlug = function(slug) { 
 
     return svc.retrieveProjectById(slug) 
 
    } 
 

 

 
    function init(index) { 
 
    \t console.log('init'); 
 
     return svc.getProjects().then(function(data) { 
 
      svc.cachedProjects = data.data.projects; 
 
     }); 
 
    } 
 

 

 

 

 

 
    return svc; 
 

 

 

 
}]);

describe('Project Service', function() { 
 
    beforeEach(module('myApp')); 
 
    var ProjectSvc, $httpBackend; 
 
    var $q, $rootScope; 
 

 
    beforeEach(inject(function(_ProjectSvc_, _$httpBackend_, _$q_, _$rootScope_) { 
 
    // The injector unwraps the underscores (_) from around the parameter names when matching 
 
    ProjectSvc = _ProjectSvc_; 
 
    $httpBackend = _$httpBackend_; 
 
    $q = _$q_; 
 

 
    $rootScope = _$rootScope_; 
 

 
    spyOn(ProjectSvc, 'retrieveProjectBySlug').and.callFake(function() { 
 
     var defer = $q.defer(); 
 
     defer.resolve(); 
 
     return defer.promise; 
 
    }); 
 
    })); 
 

 

 
    describe('.retrieveProjectBySlug()', function() { 
 
    it('test promise in service', function() { 
 

 
     var project_url = 'https://dl.dropboxusercontent.com/u/2122820/hosted_json/project.json'; 
 
     //$httpBackend.expectGET(project_url).respond(200, {data: null}); 
 

 
     console.log('-------------'); 
 
     var project; 
 
     ProjectSvc.retrieveProjectBySlug('monopoly-checker').then(function(data) { 
 
     project = data; 
 
     console.log(project); 
 
     $rootScope.$apply(); 
 
     console.log('project', project); 
 

 
     }); 
 

 
     expect(project.length).toBe(1); 
 
    }); 
 
    }); 
 
});
http://stackoverflow.com/questions/ask#

、私が取得:

1) test promise in service 
Project Service .retrieveProjectBySlug() 
TypeError: Cannot read property 'length' of undefined 

約束は決して解決されないと思われるので、projectは常に未定義です。直せますか ?それが助け場合

は、完全なソースコードはhttps://github.com/rattanakchea/rattanakchea.github.io/tree/test

+1

約束が解決される前にあなたの期待は実行されます。したがって、未定義ですか? –

答えて

1

$rootScope.$apply()が約束の外に呼び出されるべきである:

ProjectSvc.retrieveProjectBySlug('monopoly-checker').then(function(data) { 
    project = data; 
    console.log(project); 
    console.log('project', project); 
    }); 

    $rootScope.$apply(); 

$q約束がサイクルを消化するために結ばれ、約束のチェーンがダイジェストで呼び出されます。

Jasmine promise matchersを使用することを検討すると、$q約束事を解く必要がなくなります。

+0

私はあなたが提案したことを試してみました: '1)サービスのテスト約束 プロジェクトサービス.retrieveProjectBySlug() TypeError:未定義のプロパティ 'length'を読み取れません。 – rattanak

+0

約束自体は、回答。 'defer.resolve()'は 'undefined'で解決されるので、未定義です。 – estus