单元测试$scope.$on AngularJS

单元测试$scope.$on AngularJS,angularjs,unit-testing,karma-jasmine,Angularjs,Unit Testing,Karma Jasmine,大家好,我正在努力测试$的功能,我正在寻找任何关于这方面的建议或帮助: 控制器 $scope.$on("sampleFilesSelected", function(event, args) { $scope.sampleFiles = args.newSampleFiles; }); TypeError: Unable to get property 'newSampleFiles' of undefined or null re

大家好,我正在努力测试$的功能,我正在寻找任何关于这方面的建议或帮助:

控制器

  $scope.$on("sampleFilesSelected", function(event, args) {
                $scope.sampleFiles = args.newSampleFiles;
            }); 
TypeError: Unable to get property 'newSampleFiles' of undefined or null reference
        undefined
规格

describe('Testing a $.on', function() {
  var $scope = null;
  var ctrl = null;


  beforeEach(module('test'));

  it('should invoke myEvent when "myEvent" broadcasted', inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();

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

    $scope.$broadcast('myEvent');
    expect($scope.sampleFilesSelected).toBe(true);
  }));
});
错误

  $scope.$on("sampleFilesSelected", function(event, args) {
                $scope.sampleFiles = args.newSampleFiles;
            }); 
TypeError: Unable to get property 'newSampleFiles' of undefined or null reference
        undefined

您应该向事件传递一个值,在断言之前调用$digest:

$scope.$broadcast('myEvent', { 'newSampleFiles' : true } );
$scope.$digest();
expect($scope.sampleFilesSelected).toBe(true);
此代码

$scope.$broadcast('myEvent');
未传递任何args,因此args.newSampleFiles会抛出错误,因为args未定义

你需要通过args-我不知道你是怎么做到的

然而,我想说。。。单元测试用于测试控制器代码,而不是真正用于测试事件处理。你的例子有点像边缘案例。我很想使用E2E测试和量角器来测试事件处理

我将重构如下

$scope.$on("sampleFilesSelected", function(event, args) {
                $scope.sampleFiles = args.newSampleFiles;
            });
会变成

$scope.myFunction = function(event, args) {
   $scope.sampleFiles = args.newSampleFiles;
}

$scope.$on("sampleFilesSelected", $scope.myFunction);
我将对$scope.myFunction进行单元测试。并将$scope.$的测试留给E2E量角器测试


希望这能有所帮助

您犯了三个错误,第一个错误是您在控制器中收听/订阅名为
samplefileselected
的事件,但在测试中,您正在向任何收听名为
myEvent
的事件的人广播

其次,一旦上述问题得到解决,您应该在触发事件后运行
$scope.$digest()
循环,然后您可以使用
expect(…)
跟踪它


第三,正如其他人提到的,当$broadcast…ing时,您应该将数据作为第二个参数传递

我同意这是一种更好的编写方法。它不是为了更好地编写它——它允许它在不依赖事件触发的情况下进行单元测试——事件本身可以在量角器中进行测试