2013-05-15 25 views
9

我正在使用AngularJS + Karma。 configService管理我的應用程序的設置(例如,背景顏色,是否處於調試模式,一般權限等)。它使用$ http加載初始數據。我成功地爲服務寫了測試,但我的指令和控制器使用它。AngularJS + Karma:在單元測試指令或控制器時重新使用模擬服務

當我編寫指令的單元測試時,我不得不嘲笑服務。

我知道我可以做:

spyOn(configService, 'getBackgroundColor').andCallFake(function (params) { 
    return "red"; 
}); 

,但服務有25+的方法和初始數據加載。我不想在每個測試套件中編寫(並維護)這個spyOn事物。更重要的是,我使用$ http在工廠加載數據,並且也應該嘲笑。如果我只是注入服務並模擬調用,我仍然會發出http請求。

你認爲什麼是重用模擬的最佳方式?

+0

你只是想在很多測試中分享服務的模擬嗎?或者你在尋找一種方法來模擬$ http調用並在你的指令和控制器測試中使用該服務? –

+0

在許多測試套件中共享服務的模擬。更具體地說,避免在beforeEach()之前複製粘貼。昨天,我在模塊myapp.mocks中創建了一個服務,並將它包含在testacular.conf.js中,然後使用'module(myapp.mocks)'加載它。我還提取了我的服務器對另一個文件的響應,並創建了一個'var RESPONSE_SERVER = {json here}'。如果這聽起來像是一個很好的解決方案,我會詳細說明並在 –

+1

以下回答我自己,這正是我要推薦的。我創建了一個.js文件,它只包含一個我調用來創建模擬的簡單的舊javascript函數。另一個簡單的舊javascript功能來配置測試的服務器響應。就像你說的,如果你用json響應來定義一個全局變量,那麼你可以在你的測試中使用它來進行比較。 –

回答

0

我創建了一個.js文件,它只包含一個我調用來創建模擬的普通的舊javascript函數。另一個簡單的舊javascript功能來配置測試的服務器響應。而像你說的,如果你定義與JSON響應一個全局變量,那麼你可以使用在你的測試來比較

8

而是與間諜噴塗測試代碼,你可以創建服務的適當模擬它自己的模塊並將其添加到需要它的任何測試中。

控制器單元測試位於test/spec/modules/user/controller.js文件中。

模擬服務位於測試/模擬/模塊/用戶/ service.js文件中。

對於控制器的方法:

$scope.refreshList = function() { 
    UserService.all(pageNumber, size, sort, function(data) { 
    $scope.users = data.content; 
    $scope.page = data.page; 
    }); 
}; 

嘲笑服務:

(function() { 

'use strict'; 

angular.module('app.user.mock', ['app.user']); 

angular.module('app.user.mock').factory('UserServiceMock', 
    ['$q', 
    function($q) { 
    var factory = {}; 

    factory.mockedUsers = { 
     content: [ { firstname: 'Spirou', lastname: 'Fantasio', email: '[email protected]', workPhone: '983743464365' } ], 
     page: '1' 
    }; 

    factory.search = function(searchTerm, page, size, sort, callback) { 
     var defer = $q.defer(); 
     defer.resolve(this.mockedUsers); 
     defer.promise.then(callback); 
     return defer.promise; 
    }; 

    factory.all = function(page, size, sort, callback) { 
     var defer = $q.defer(); 
     defer.resolve(this.mockedUsers); 
     defer.promise.then(callback); 
     return defer.promise; 
    }; 

    return factory; 
    } 
]); 

})(); 

和控制器單元測試:

(function() { 

'use strict'; 

var $scope; 
var listController; 
var UserServiceMock; 

beforeEach(function() { 
    module('app.project'); 
    module('app.user.mock'); // (1) 
}); 

beforeEach(inject(function($rootScope, _UserServiceMock_) { 
    $scope = $rootScope.$new(); 
    UserServiceMock = _UserServiceMock_; // (2) 
})); 

describe('user.listCtrl', function() { 

    beforeEach(inject(function($controller) { 
    listController = $controller('user.listCtrl', { 
     $scope: $scope, 
     UserService: UserServiceMock 
    }); 
    })); 

    it('should have a search function', function() { // (3) 
    expect(angular.isFunction(UserServiceMock.search)).toBe(true); 
    }); 

    it('should have an all function', function() { 
    expect(angular.isFunction(UserServiceMock.all)).toBe(true); 
    }); 

    it('should have mocked users in the service', function() { 
    expect(UserServiceMock.mockedUsers).toBeDefined(); 
    }); 

    it('should set the list of users in the scope', function(){ 
    expect($scope.users).not.toEqual(UserServiceMock.mockedUsers); 
    $scope.refreshList(); 
    $scope.$digest(); 
    expect($scope.users).toEqual(UserServiceMock.mockedUsers.content); 
    }); 

}); 

})(); 

您添加包含app.user.mock模塊模擬服務(1)並將模擬服務注入控制器(2)。

然後你可以測試你的模擬服務已被注入(3)。

+0

你知道有什麼辦法讓茉莉花變成這樣的模擬嗎?所以我可以使用'jasmine.spyOn'來代替手動跟蹤調用。 – dshepherd

相關問題