2017-02-17 156 views
0

我與因緣/茉莉花測試框架的角度JS應用程序的工作角度的單元測試工廠,我需要測試工廠,返回一個HTTP承諾,但它總是返回undefined使用HTTP請求

這裏是我廠

angular.module('GithubUsers').factory('Users',['$http','$q',function($http,$q){ 
 
    return{ 
 
    getAllUsers:function(){ 
 
     var defered= $q.defer(); 
 
     $http({ 
 
     url:'https://api.github.com/users', 
 
     method:'GET' 
 
     }).then(function(users){ 
 
     defered.resolve(users.data); 
 
     },function(err){ 
 
     defered.reject(err); 
 
     }) 
 
     return defered.promise; 
 
    } 
 
    } 
 
}])

這裏是我的測試

更新感謝您的回答我修改了代碼以下,但沒有我得到這個錯誤

可能未處理的拒絕:{「地位」:0,「配置」:{「方法」:「GET」,」 transformRequest「:[null],」transformResponse「:[null],」jsonpCallbackParam「:」callback「,」url「:」https://api.github.com/users?since=1「,」headers「:{」Accept「:」application/json,text/plain,/ 「},」 緩存 「:假},」 狀態文本 「:」「}拋出

describe('Test Users Factory',function(){ 
 
    var $controller, 
 
    Users, 
 
    $rootScope, 
 
    $httpBackend, 
 
    $q; 
 
    beforeEach(module('GithubUsers')); 
 
    beforeEach(inject(function(_$controller_,_Users_,_$rootScope_,_$httpBackend_,_$q_){ 
 
    $controller = _$controller_; 
 
    Users = _Users_; 
 
    $rootScope= _$rootScope_; 
 
    $httpBackend=_$httpBackend_; 
 
    
 
    
 
    })) 
 
    
 
    it('should get users',function(){ 
 
    
 
    var result; 
 

 
    $httpBackend.whenGET('https://api.github.com/users?since=1').respond(function(){ 
 
     return {data:[{id:2}],status:200}; 
 
    }) 
 
    Users.getAllUsers().then(function(res){ 
 
     result = res; 
 
    }); 
 
    $httpBackend.flush(); 
 
    $rootScope.$digest() 
 
    expect(result).toBeTruthy(); 
 
    }) 
 
})

在此先感謝!

回答

1

我認爲你需要傳遞一個函數,它返回一個數組,其中有3個項目到whenGET()。 響應()。

也許,你可以嘗試這樣的事:

beforeEach(angular.mock.inject(function (User, $httpBackend, $http) { 
    ... 
    this.withOKUsers = function() { 
      var i1 = new User(); 
      i1.id = 10; 
      return [200, JSON.stringify([ i1]), {}]; 
    } ... 
})); 
...  
it('should get users',function(){ 
$httpBackend 
    .whenGET('https://api.github.com/users') 
    .respond(this.withOKUsers); 

Users.getAllUsers().then(function(res){ 
    result = res; 
});  

$httpBackend.flush(); 
expect(result).not.toBeNull(); 
... 

(我更喜歡安排它()子句外規格爲更好的可讀性)

+0

感謝您的回覆,但不幸的是它沒有爲我工作 –

+0

確實忘了添加flush()方法。總是在回調和期望值之間沖洗 –

+0

感謝您請檢查我更新的問題 –

1

你缺少$ httpBackend.flush ();在您的測試方法調用後調用。它會調用成功/錯誤,然後分離並正確解析$ q的承諾。對於更多測試,我會將$ httpBackend.whenGET分別移動到每個測試用例中,以便稍後可以根據用例進行驗證,但這僅僅是我個人的看法。

我發現它有點可疑,你在一個測試中混合$控制器和工廠。我建議將它們分開,並在控制器測試中檢查對服務方法的調用,並在一個相關測試中自己做一個$ httpBackend的東西。

下面我粘貼你的測試與我的更正。現在對我的作品:

describe('Test Users Factory', function() { 
var Users, 
$rootScope, 
$httpBackend, 
$q; 
beforeEach(module('app.utils')); 
beforeEach(inject(function (_Users_, _$rootScope_, _$httpBackend_, _$q_) { 
    Users = _Users_; 
    $rootScope = _$rootScope_; 
    $httpBackend = _$httpBackend_; 
})); 

afterEach(function() { 
    $httpBackend.verifyNoOutstandingExpectation(); 
    $httpBackend.verifyNoOutstandingRequest(); 
}); 

it('should get users', function() { 
    var result; 

    $httpBackend.when('GET', "https://api.github.com/users").respond({ data: [{ id: 2 }], status: 200 }); 

    Users.getAllUsers().then(function (res) { 
     result = res; 
     expect(result).toBeTruthy(); 
    }); 


    $httpBackend.flush(); 
    $rootScope.$digest(); 
}); 

重要告示: 1)afterEach - 檢查,如果沒有掛起的請求,保持您的通話 2)你的網址與參數不同,因爲後= 1?。但是你不把它作爲你的代碼中的一個參數,所以我不明白爲什麼你添加了這個參數。 也許考慮與url和參數串連接?

+0

非常感謝您的澄清我不知道關於'flush'功能之前,請您檢查我的更新問題 –