2015-11-23 44 views
5

我正在嘗試使用Karma和Jasmine對我的AngularJS應用程序進行單元測試。我想嘲笑$ http服務。爲此,我使用$ httpBackend方法。下面是我的服務,我想測試:

angular.module('MyModule').factory('MyService', function($http, $log, $parse, $q, $timeout, $filter, MyOtherService1, MyOtherService2){ 
var service = {}; 
    service.getSomething = function(id){ 
    return $http.get('/somePath/subpath/' + id); 
    } 
}); 

這項服務我的單元測試是:

describe("myTest", function(){ 
    var myService, $httpBackend, scope, mockMyOtherService1, mockMyOtherService2; 

    var myResponse = 
    { 
     foo:'bar' 
    }; 

    beforeEach(module("MyModule")); 

    beforeEach(inject(function(_MyService_, $injector){ 

     $httpBackend = $injector.get('$httpBackend'); 
     myService = _MyService_; 
     scope = $injector.get('$rootScope').$new(); 
     mockMyOtherService1 = $injector.get('MyOtherService1'); 
     mockMyOtherService2 = $injector.get('MyOtherService2'); 

    })); 

    beforeEach(function(){ 
     //To bypass dependent requests 
     $httpBackend.whenGET(/\.html$/).respond(200,''); 
    }); 

    //If I uncomment the below afterEach block, the same error is shown at next line. 
    /*afterEach(function() { 
     $httpBackend.verifyNoOutstandingExpectation(); 
     $httpBackend.verifyNoOutstandingRequest(); 
    });*/ 

    //This test passes successfully 
    it("should check if service is instantiated", function() { 
     expect(myService).toBeDefined(); 
    }); 

    //This test passes successfully 
    it("should expect dependencies to be instantiated", function(){ 
     expect($httpBackend).toBeDefined(); 
    }); 

    //The problem is in this test 
    it("should get the getSomething with the provided ID", function() { 
     $httpBackend.whenGET('/somePath/subpath/my_123').respond(200,myResponse);    
     var deferredResponse = myService.getSomething('my_123'); 

     //The error is shown in next line. 
     $httpBackend.flush();  

     //If I comment the $httpBackend.flush(), in the next line, the $$state in deferredResponse shows that the Object that I responded with is not set i.e. it does not matches the 'myResponse'. 
     expect(deferredResponse).toEqual(myResponse); 

    }); 
}); 

這是一個緊急的問題,我需要儘快就同一幫助。我會非常感謝你的回答。

回答

1

問題是我需要在我的spec文件中注入$ location,即使它們沒有注入到服務中。注射後,一切運作良好!希望這可以幫助陷入相同情況的人。

+1

這不適用於我:P –

+0

@TusharRaj您面臨的確切問題是什麼?請在stackoverflow上指出我的問題 – Jagrut

1

您將得到您的服務承諾。因此,將您的測試代碼更改爲:

//The problem is in this test 
it("should get the getSomething with the provided ID", function (done) { 
    $httpBackend.expectGET('/somePath/subpath/my_123').respond(200,myResponse); 
    var deferredResponse = myService.getSomething('my_123'); 

    deferredResponse.then(function (value) { 
    expect(value.data).toEqual(myResponse); 
    }).finally(done); 

    $httpBackend.flush(); 
}); 
+0

我試過你的代碼,但它給出了相同的錯誤,因爲錯誤在$ httpBackend.flush()行。它不在該行本身之後執行。如果我註釋掉$ httpBackend.flush()行,那麼它可以工作。但是我需要$ httpBackend.flush()和afterEach()塊。 – Jagrut

+0

我更新了答案,將flush()調用移到了最後。它現在可以在我的機器上運行。你可以再試一次更新的代碼嗎? – ogugger

+0

還是一樣的錯誤!我認爲我忽略了一些東西,但我無法找到答案。即使我不寫任何它()塊,afterEach()應該工作,但它也不工作!所以我不得不將它評論出來並繼續進行下去。但即使如此,我堅持在$ httpBackend.flush()! – Jagrut

1

我在將項目從Angular 1.2更新到1.4時最近遇到了這個問題。測試代碼如下所示:

it('should call /something', function(){ 
    httpBackend.expectGET('/something').respond(200); 
    scope.doSomething(); 
    httpBackend.flush(); 
}); 

錯誤是infdig過去的10次迭代。這是由調用.flush()方法引起的。我發現這似乎是因爲在doSomething()內沒有未完成的承諾。

一旦我在doSomething()或內部方法中的某處添加承諾,infdig問題就消失了。

我懷疑 - 這是100%的投機行爲,所以不要讓它影響你的發展 - 這是因爲httpBackend做一些弄虛作假等承諾,這可能涉及到多次消化,直到有一個變化。由於沒有承諾,所以沒有任何變化 - 無限的摘要。

相關問題