2014-10-28 39 views
0

測試服務,我做這個控制器AngularJs:茉莉

app.controller('controller',['$scope','httpServices',function($scope,httpServices){ 
    $scope.items= undefined; 

    httpServices.getItems(function(items){ 
     $scope.items= items; 
    }); 
}]); 

和我寫了這個測試

describe('controller', function() { 
     beforeEach(inject(function ($rootScope, $controller) { 
      scope = $rootScope.$new(); 
      controller = $controller('controller', { 
       '$scope': scope 
      }); 
     })); 
     it('defined', function() { 
      expect(scope.items).toBeUndefined(); 
     }) 
    }); 

我如何測試scope.items已經叫售後服務?

+0

任何你沒有從'httpServices.getItems'返回承諾的原因? – 2014-10-29 07:54:32

回答

0

我假設你的服務httpServices正在發出一些http請求。因此,您應該使用mock-backend服務來測試您的控制器。

這樣的事情,注意,我已經在代碼中提出的意見:

describe('Your specs', function() { 
    var $scope, 
     $controller, 
     $httpBackend; 

    // Load the services's module 
    beforeEach(module('yourApp')); 

    beforeEach(inject(function(_$controller_, $rootScope, _$httpBackend_) { 
    $scope = $rootScope.$new(); 
    $httpBackend = _$httpBackend_; 
    $controller = _$controller_; 

    //THIS LINE IS VERY IMPORTANT, HERE YOU HAVE TO MOCK THE RESPONSE FROM THE BACKEND 
    $httpBackend.when('GET', 'http://WHATEVER.COM/API/SOMETHING/').respond({}); 

    var createController = function(){ 
     $controller('controller', {$scope: $scope}); 
    } 
    })); 

    describe('Your controller', function() { 
    it('items should be undefined', function() { 
     createController(); 
     expect(scope.items).toBeUndefined(); 
    }); 

    it('items should exist after getting the response from the server', function() { 
     //THIS LINE IS ALSO VERY IMPORTANT, IT EMULATES THE RESPONSE FROM THE SERVER 
     $httpBackend.flush(); 
     expect(scope.items).toBeDefined(); 
    }); 
    }); 
}); 
+0

在第二次測試中,應該期待(scope.items).toBeDefined(); – 2014-10-28 23:44:16

+0

@AbhishekJain當然,我只是改變了它。但爲什麼?舊的代碼是100%等價的:'expect(scope.items).not.toBeUndefined()'與'expect(scope.items).toBeDefined()' – Josep 2014-10-28 23:49:51

+0

相同啊!我的壞!不知道,我道歉! – 2014-10-28 23:51:59

0

問題標題指出這是測試服務,但問題的代碼看起來像一個嘗試正在測試控制器。這個答案描述瞭如何測試控制器。爲了


如果您正在測試調用httpServices.getItems控制器,那麼你需要嘲笑它/存根getItems

  • 控制它的測試
  • 不承擔的任何行爲真實httpServices.getItems。畢竟,你正在測試控制器,而不是服務。

做到這一點的方法是在beforeEach塊(在創建控制器之前調用)提供虛假實施getItems那只是保存傳遞給它的回調。

var callback; 
beforeEach(inject(function(httpServices) { 
    callback = null; 
    spyOn(httpServices, 'getItems').and.callFake(function(_callback_) { 
    callback = _callback_; 
    }); 
}); 

在測試中,您可以調用此回調函數,傳入一些假數據,並測試它是否已在示波器上正確設置。

it('saves the items passed to the callback on the scope', function() { 
    var testItems = {}; 
    callback(testItems); 
    expect($scope.items).toBe(testItems); 
}); 

由此可以看出,在http://plnkr.co/edit/Z7N6pZjCS9ojs9PZFD04?p=preview


工作。如果你想測試httpServices.getItems本身,然後單獨測試是那個地方。假設getItems調用$http,那麼您很可能需要使用$httpBackend來處理模擬響應。最有可能的是,這些測試不會實例化任何控制器,我懷疑不需要在任何範圍上做任何事情。