我正在使用AngularJS + Karma。
configService
管理我的应用程序的设置(例如背景颜色,它在调试模式下,一般权限......)。它使用$ http加载初始数据。我成功地为服务编写了测试,但我的指令和控制器使用它。
当我为指令编写单元测试时,我必须模拟服务。
我知道我能做到:
spyOn(configService, 'getBackgroundColor').andCallFake(function (params) {
return "red";
});
但该服务有25多种方法和初始数据加载。我不想在每个测试套件中编写(并维护)这个spyOn的东西。更重要的是,我使用$ http在工厂加载数据,这也应该被嘲笑。如果我只是注入服务并模拟调用,我仍然会发出http get请求。
您认为重用模拟的最佳方式是什么?
答案 0 :(得分:9)
您可以在自己的模块中创建适当的服务模拟,并将其添加到需要它的任何测试中,而不是使用间谍来喷涂测试代码。
控制器单元测试位于test / spec / modules / user / controller.js文件中。
模拟服务位于test / mock / modules / user / 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: 'spirou@yahoo.se', 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)。
答案 1 :(得分:0)
我创建了一个.js文件,它只包含一个简单的旧javascript函数,我调用它来创建mock。另一个普通的旧javascript函数来配置服务器响应以进行测试。就像你说的那样,如果用json响应定义一个全局变量,那么你可以在测试中使用它来比较