9

我正在使用 AngularJS + Karma。 configService管理我的应用程序的设置(例如背景颜色,是否处于调试模式,一般权限......)。它使用 $http 加载初始数据。我为服务成功编写了测试,但我的指令和控制器使用它。

当我为指令编写单元测试时,我必须模拟服务。

我知道我可以做到:

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

但该服务有 25 多种方法和初始数据加载。我不想在每个测试套件中编写(和维护)这个 spyOn 东西。更重要的是,我在工厂中使用 $http 加载数据,这也应该被嘲笑。如果我只是注入服务并模拟调用,我仍然会发出 http get 请求。

您认为重用模拟的最佳方式是什么?

4

2 回答 2

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)。

于 2015-04-12T17:40:11.357 回答
0

我创建了一个 .js 文件,其中只包含一个普通的旧 javascript 函数,我调用它来创建模拟。另一个普通的旧 javascript 函数,用于配置服务器响应以进行测试。就像你说的,如果你用 json 响应定义一个全局变量,那么你可以在你的测试中使用它来比较

于 2014-04-22T21:08:33.133 回答