2013-01-31 59 views
3

我想對使用Angular $資源進行的REST請求做一些基本的測試。 服務代碼工作得很好。

'use strict'; 

angular.module('lelylan.services', ['ngResource']). 
    factory('Device', ['Settings', '$resource', '$http', function(Settings, $resource, $http) { 

    var token = 'df39d56eaa83cf94ef546cebdfb31241327e62f8712ddc4fad0297e8de746f62'; 
    $http.defaults.headers.common["Authorization"] = 'Bearer ' + token; 

    var resource = $resource(
     'http://localhost:port/devices/:id', 
     { port: ':3001', id: '@id' }, 
     { update: { method: 'PUT' } } 
    ); 

    return resource; 
    }]); 

我在指令中使用設備資源,它的工作原理。當我開始對服務進行一些測試時,出現問題 。以下是一個示例測試,其中我使用$ httpBackend嘲笑了 HTTP請求,並向嘲弄的URL發出請求。

不幸的是它不返回任何東西,雖然有請求。我很確定這個 ,因爲如果對另一個URL發出請求,測試套件會自動產生一個錯誤。 我一直花費很多時間,但沒有解決方案。這裏是測試代碼。

'use strict'; 

var $httpBackend; 

describe('Services', function() { 

    beforeEach(module('lelylan')); 

    beforeEach(inject(function($injector) { 
    var uri = 'http://localhost:3001/devices/50c61ff1d033a9b610000001'; 
    var device = { name: 'Light', updated_at: '2012-12-20T18:40:19Z' }; 
    $httpBackend = $injector.get('$httpBackend'); 
    $httpBackend.whenGET(uri).respond(device) 
    })); 

    describe('Device#get', function() { 
    it('returns a JSON', inject(function(Device) { 
     device = Device.get({ id: '50c61ff1d033a9b610000001' }); 
     expect(device.name).toEqual('Light'); 
    })); 
    }); 
}); 

由於設備未加載,這是錯誤。

Expected undefined to equal 'Light'. 
Error: Expected undefined to equal 'Light'. 

我也試過用以下解決方案,但它不進入功能 檢查預期。

it('returns a JSON', inject(function(Device) { 
    device = Device.get({ id: '50c61ff1d033a9b610000001' }, function() { 
    expect(device.name).toEqual('Light'); 
    }); 
})); 

任何建議或鏈接來解決這個問題真的很感激。 非常感謝。

回答

5

你非常接近,唯一缺少的是對$httpBackend.flush();的調用。工作測試看起來如下:

it('returns a JSON', inject(function(Device) { 
    var device = Device.get({ id: '50c61ff1d033a9b610000001' }); 
    $httpBackend.flush(); 
    expect(device.name).toEqual('Light'); 
})); 

和plunker現場測試:http://plnkr.co/edit/Pp0LbLHs0Qxlgqkl948l?p=preview

您還可能要檢查docs for the $httpBackend mock

+0

非常感謝。我正在做一些測試。我完全錯過了#flush部分。還非常感謝真正好的現場示例。愛它。 –

0

在更高版本的angular中,我使用的是1.2.0rc1,您還需要在$ apply中調用它或在範圍上調用$ digest。除非你做這樣的事情,否則不會撥打資源:

var o, back, scope; 

beforeEach(inject(function($httpBackend, TestAPI,$rootScope) { 
    o = TestAPI; 
    back = $httpBackend; 
    scope = $rootScope.$new(); 

})); 

it('should call the test api service', function() { 
    back.whenGET('/api/test').respond({}); 
    back.expectGET('/api/test'); 
    scope.$apply(o.test()); 
    back.flush(); 
});