为什么anglar.mock.module不提供像$提供常量的值

时间:2016-04-20 16:38:34

标签: angularjs unit-testing jasmine

我查看了angular.mock.module的文档和examples others plunker使用它的文档但是我的用例中似乎遇到了一个问题不明白。

我正在使用angular(2.4.1)运行Jasmine(1.4.9)测试,我将我的角度应用程序分成多个模块。当我试图模拟我的应用程序的某些部分进行单元测试时,我想模拟整个模块(或提供程序),以便我只公开我使用的部分。

这是一个非常简单的应用,其主模块plunker取决于plunker.serviceplunker.service取决于plunker.constant

var app = angular.module('plunker', ['plunker.service']);

app.controller('MainCtrl', function($scope, valueService, appService) {
  $scope.init = function() {
    $scope.appValue = valueService.getValue();
    $scope.appIsRunning = appService.getStatus();
  };
});

angular.module('plunker.service', ['plunker.constant'])
  .service('appService', function(appSettings) {
    var vm = this;

    vm.getStatus = function () {
      if (appSettings.isRunning) {
        return true;
      } else {
        return false;
      }
    };
  })
  .service('valueService', function(valueSettings) {
    var vm = this;

    vm.getValue = function () {
      return valueSettings.value;
    }
  });

angular.module('plunker.constant', [])
  .constant('appSettings', { isRunning: true })
  .constant('valueSettings', { value: 10 });

在我的Jasmine测试中,我有beforeEach()使用module(又名angular.mock.module)注册我的模块。

我看过3种使用module

的方法
  • string
  • function$provide
  • object

您可以在下面看到我使用module('plunker')string)注册我的主模块,我有3种方法可以模拟我的appSettings常量(ABC)。您会注意到function $provide.constant工作正常但function $provide.value没有,object没有。{/ p>

beforeEach(function() {
    module('plunker');

    function useFunction(typeofProvider) {
      module(function($provide) {
        $provide[typeofProvider]('appSettings', { isRunning: false });
      });
    }

    function useObject() {
      module({
        appSettings: { isRunning: false }
      });
    }

    // A. THIS WORKS! //
    useFunction('constant');

    // B. THIS DOES NOT //
    // useFunction('value');

    // C. THIS ALSO DOES NOT!! //
    // useObject();

    inject(function($rootScope, $controller) {
      $scope = $rootScope.$new();

      ctrl = $controller('MainCtrl', {
        $scope: $scope
      });
    });  
});

我也看到人们使用以下语法......

beforeEach(function() {
    var mockService = function () {
        var mockValue = 10;

        this.value = mockValue;
    };

    // D.
    module('a.module.name', function newProviders($provide){
        $provide.service('realService', mockService);
    });
});

我的问题

  1. 在我的测试代码中,为什么A.有效但B.C.没有?
  2. D.是否相当于调用module('a.module.name');后跟module(function newProviders($provide) { ... });?将两者置于相同的module()调用中是否会对事物的注册方式产生任何特殊影响,还是只是简写? (基于文档,它应该是一个简写)
  3. 与Jasmine相关,具体来说,每次执行都会以相同的从上到下的顺序运行所有beforeEach()次调用吗?
  4. 以上是我的{{3}}申请和茉莉花代码

    由于

1 个答案:

答案 0 :(得分:0)

这是因为Angular进样器的工作原理。实际上,Angular中有两种不同的注射器。 The one$injector块中的config提供)与服务提供商进行交易。 Another one(在其他任何地方可用$injector)处理服务实例。 Providersinstances在内部进行缓存和存储。

$provide.constant('service')在通话时创建名为“服务”的both provider and instance

所有其他类型的服务都是懒惰的实例化。他们在调用时创建“serviceProvider”提供程序,但在第一次注入时创建“service”实例。

由于Angular服务实例是单例,因此它在实例化之前引用实例缓存。如果实例位于缓存中,则会重用它并且不会实例化。急切地实例化constant服务实例,因此只有另一个constant可以覆盖该实例。

此示例中angular.mock.module are shortcuts for $provide.valueuseObject()中的对象属性等于useFunction('value')

只要模块顺序保持不变,

module('a.module.name', function ($provide) { ... });

确实是

的捷径
module('a.module.name');
module(function ($provide) { ... });

由于appSettings块中没有使用config对象(constant服务的主要用途),因此更方便value