【问题标题】:How do I test a controller that watches for changes on an injected service?如何测试监视注入服务更改的控制器?
【发布时间】:2014-06-28 06:58:33
【问题描述】:

我正在使用服务在控制器之间共享数据。如果服务上的值发生变化,我想更新我的控制器上的一些数据绑定。为此,我使用了 $scope.$watchCollection(因为我正在观看的值是一个简单的数组)。我无法弄清楚如何在 Jasmine + Karma 中进行测试。

这是一个简单的控制器 + 服务设置,类似于我在我的应用中所做的(但非常简化):

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

// A Controller that depends on 'someService'
app.controller('MainCtrl', function($scope, someService) {
  $scope.hasStuff = false;

  // Watch someService.someValues for changes and do stuff.
  $scope.$watchCollection(function(){
    return someService.someValues;
  }, function (){
    if(someService.someValues.length > 0){
      $scope.hasStuff = false;
    } else {
      $scope.hasStuff = true;  
    }

  });
});

// A simple service potentially used in many controllers
app.factory('someService', function ($timeout, $q){
  return {
    someValues: []
  };
});

这是我尝试过的一个测试用例(但不起作用):

describe('Testing a controller and service', function() {
  var $scope, ctrl;
  var mockSomeService = {
    someValues : []
  };

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

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

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

  it('should update hasStuff when someService.someValues is changed', function (){
    expect($scope.hasStuff).toEqual(false);

    // Add an item to someService.someValues
    someService.someValues.push(1);

    //$apply the change to trigger the $watch.
    $scope.$apply();

    //assert
    expect($scope.hasStuff).toEqual(true);
  });

});

我想我的问题是双重的:

如何正确模拟控制器中使用的服务? 然后如何测试 $watchCollection 函数是否正常工作?

这是上面代码的一个 plunkr。 http://plnkr.co/edit/C1O2iO

【问题讨论】:

    标签: angularjs jasmine karma-runner angularjs-service


    【解决方案1】:

    您的测试(或您的代码)不正确。

    http://plnkr.co/edit/uhSdk6hvcHI2cWKBgj1y?p=preview

    mockSomeService.someValues.push(1); // instead of   someService.someValues.push(1);
    

       if(someService.someValues.length > 0){
          $scope.hasStuff = true;
        } else {
          $scope.hasStuff = false;  
        }
    

    或者你的期望没有意义

    我强烈建议您对 javascript (jslint/eslint/jshint) 进行 lint,以发现第一个类似的愚蠢错误。否则,您将在编写 javascript 时遇到痛苦的经历。 jslint 会检测到您使用的变量在范围内不存在。

    【讨论】:

    • 是的,我看到了错误,但不知道该怎么办(这就是我在 Stack Overflow 上询问的原因)。我想我没有意识到在测试中更改 mockSomeService 会触发 $change.$watchCollection。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    • 2012-05-03
    • 2016-01-18
    相关资源
    最近更新 更多