25

我正在尝试学习如何为 AngularJS 编写单元测试。我从一开始就用

angular.module( ... ).config( ... )

我想测试一下配置里面的内容。以下是相关部分的外观:

angular.module('ogApp', ['ngCookies','ui.router','ogControllers','ogServices','ogDirectives','ogMetricsData'])

.config([
  '$stateProvider', '$locationProvider',
  function ($stateProvider, $locationProvider) {
    $stateProvider.
      state('login', {
        templateUrl: 'connect.html'
      }).state('addViews', {
        templateUrl: 'add-views.html'
      }).state('dashboard', {
        templateUrl: 'dashboard.html'
      });
    $locationProvider.
      html5Mode(true).
      hashPrefix('!');
  }
]);

我认为测试此代码的最简单方法是为$stateProviderand注入模拟$locationProvider。然后执行配置阶段。之后,断言如何$stateProvider以及$locationProvider应该是什么样子。

如果我的想法是正确的,那么我的问题是,我不知道如何将这些模拟注入模块并从测试中执行其配置阶段。

你能告诉我如何测试这段代码吗?

4

3 回答 3

11

以下是如何访问您的提供者进行单元测试:

describe('yourProvider', function () {
    var provider;

    // Get the provider
    beforeEach(module('app', function (yourProvider) {
        // This callback is only called during instantiation
        provider = yourProvider;
    });

    // Kick off the above function
    beforeEach(inject(function () {}));

    it('does its thing', function () {
        expect(provider.someMethod()).toEqual('your results');
    });
});

我还没有想出一个非常简单的注入模拟的方法,但是你可以很容易地窥探方法,这已经足够接近了。如果您需要从依赖提供者的 .$get() 方法返回的模拟,您也可以使用另一个间谍来执行此操作。这个例子说明了返回一个模拟和设置一个额外的间谍。

describe('yourProvider', function () {
    var dependency, mock, provider;

    beforeEach(module('app', function (dependencyProvider) {
        dependency = dependencyProvider;
        mock = jasmine.createSpyObj('dependency', [
            'methodsGoHere'
        ]);
        spyOn(dependency, 'methodName');
        spyOn(dependency, '$get').andReturn(mock);
    }, function (yourProvider) {
        provider = yourProvider;
    });

    beforeEach(inject(function () {}));

    it('does its thing', function () {
        expect(provider.someMethod()).toEqual('your results');
        expect(dependency.methodName).toHaveBeenCalled();
    });

    it('returns the mock from $get', function () {
        expect(dependency.$get).toBe(mock);
    });
});
于 2014-07-22T13:19:19.717 回答
0

您可以使用Jasmine 的 createSpyandcreateSpyObj创建模拟服务并 angular-mocks.js注入它们。

有关在此处注入模拟的更多说明:将模拟注入 AngularJS 服务

在我为我的指令编写的这个测试中,您可以看到以下内容:

  • 第 9 行包括来自 google cdn 的 angular-mock
  • 第 19 和 20 行创建一个假的 rootScope 对象
  • 第 21 和 22 行创建假 q 服务
  • 第 42 行设置提供程序以将伪造品注入服务
  • 第 48 行实例化具有假货的服务(该服务被注入到被测指令中)
  • 第 53 行调用正在测试的方法
  • 第 55 - 59 行断言假货的状态
于 2013-09-24T15:44:36.957 回答
-1

我会创建一个指向函数的工厂......然后在配置函数中也调用该函数。这样你就可以对工厂进行单元测试:

angular.module('ogApp', ['ngCookies','ui.router','ogControllers','ogServices','ogDirectives','ogMetricsData']);

// Configuration factory for unit testing
angular.module('ogApp')
.factory('configuration', configuration);

configuration.$inject = ['$stateProvider', '$locationProvider'];

function configuration($stateProvider, $locationProvider) {
  return {
    applyConfig: function () {
      $stateProvider.
        state('login', {
          templateUrl: 'connect.html'
        }).state('addViews', {
          templateUrl: 'add-views.html'
        }).state('dashboard', {
          templateUrl: 'dashboard.html'
        });
      $locationProvider.
        html5Mode(true).
        hashPrefix('!');
    };
}

// Call above configuration function from Angular's config phase
angular.module('ogApp')
.config([
  '$stateProvider', '$locationProvider',
  function ($stateProvider, $locationProvider) {
    var config = configuration($stateProvider, $locationProvider);
    config.applyConfig();
  }
]);

您可以像使用任何其他工厂一样对配置工厂进行单元测试并注入模拟。

于 2014-11-12T16:18:24.830 回答