【问题标题】:AngularJS Jasmine Test - Element Isolate Scope undefinedAngularJS Jasmine 测试 - 元素隔离范围未定义
【发布时间】:2016-06-24 01:14:09
【问题描述】:

我正在尝试测试超时,但我遇到了元素范围的问题。我是编写 JS 测试的新手。

it( 'should have timer defined at start' ) 测试中,我的变量记录为未定义。这是为什么?

我认为isolateScope() 会将指令的范围拉进去?

我的测试如下所示:

https://plnkr.co/edit/IMrPd9g6HFSkgHizFF9p?p=preview

describe( 'Testing timeout', function(){
  var scope, $timeout, element;

  beforeEach(inject( function ($rootScope, $compile, _$timeout_, $injector ){
            scope = $rootScope.$new();
            $timeout = _$timeout_;

            scope.onWarning = function(){
                scope.warned = true;
            };

            element = '<div timeout on-warning="onWarning" on-timeout="onTimeout"></div>';
            element = $compile(element)(scope);

            scope.$apply();
            scope.$digest();

  }));

  it( 'should have timer defined at start', function(){
    console.log( element.isolateScope() , scope )
    expect( element.isolateScope().timeoutService.timer ).not.toBeFalsy;
  });

  it( 'should have run warning function', function(){
    $timeout.flush( 5000 );
    expect( scope.warned ).toBe( true );
  });

});

我的指令如下所示:

app.directive( 'timeout', function( timeoutService ){
  return {
    restrict: "A",
    scope: {
                onWarning: "&", // what function to fire when showing a warning
            },
            link: function( scope, elem, attr ){
                scope.timeoutService = timeoutService;
                if( !scope.onWarning ){ 
                    throw new Error( "Must provide on-warning for timeout directive." );
                }
                //console.log( scope.onWarning, scope.onTimeout );
                // register timeouts and warnings with the service
                timeoutService.onWarning = scope.onWarning; 
            }
  }
}); 

app.service( 'timeoutService', function( $timeout ){
  var _this = this;
  var timer = null;
  var time = 5000;

  this.startTimer = function(){
    timer = $timeout( function(){
      if( _this.onWarning ){
        _this.onWarning()();
      }
    }, time)
  }

  this.startTimer();

})

也许我测试不正确?

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine


    【解决方案1】:

    你需要打电话

    beforeEach(module('plunker'));
    

    在您的“测试超时”描述块中。你只是在另一个描述块中调用它

    【讨论】:

      【解决方案2】:

      我只想看看范围,因为 Angular 团队已经很好地测试了 $compile 服务,您知道这是用于指令范围的内容。说实话,我通常只使用在指令之外定义的控制器并对其进行测试。您的指令中似乎没有任何内容需要您编译它来测试它,除了您使用的是链接函数而不是控制器。

      您的指令没有将 timeoutService 附加到其范围,这很好。所以你不能看它(你不应该!)。

      AngularJS 已经有了 $timer 服务。在您自己的服务中再次包装它既不必要又容易出错,所以我不会这样做。另外,它不知道传递给您的指令的 onWarning 函数。相反,只需从您的指令中调用 $timeout 并检查它是否没有挂起的调用,或者在 $timeout.flush(); 之后数据处于正确的状态;确保测试您取消了 $destroy 上的任何未决超时。

      【讨论】:

      • 我创建的示例稍微简化了一点,但该指令的目的是在 div 空闲一段时间后向用户显示警告消息。警告功能的目的是什么
      • 对不起,错字。 $timeout 就是我的意思。你已经在使用它了。您不需要创建另一个服务,它只是现有服务的包装器并执行相同的操作(跟踪现有超时等),但其方式不如谷歌经验少的人进行彻底测试和编写团队。
      • 请注意,我非常熟悉将函数传递给稍后调用的指令。我能够查看您的代码并了解您要执行的操作,但您这样做的方式过于复杂,并且可能会在长期内给您带来问题。
      • 我知道这是不必要的复杂,但我想要一个可重用的指令,它独立于其他所有内容并且可以作为依赖项引入。
      • 您已经在服务中使用了 $timeout,并且您的指令取决于服务。因此,通过不必要的服务,您添加了一个可以消除的依赖项。但无论如何。
      猜你喜欢
      • 2015-06-11
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多