Angularjs Angular.js单元测试在运行阶段发生的事情(rootScope事件侦听)

Angularjs Angular.js单元测试在运行阶段发生的事情(rootScope事件侦听),angularjs,Angularjs,我有一些东西必须在rootScope上(也欢迎建议)一个stateChangeError事件的侦听器,该侦听器会重新路由这些事件以进行错误处理。 比如: $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error){ if(error.status === 404 ){ event.preventDefault

我有一些东西必须在rootScope上(也欢迎建议)一个stateChangeError事件的侦听器,该侦听器会重新路由这些事件以进行错误处理。 比如:

$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error){
          if(error.status === 404 ){
              event.preventDefault();
              $state.go('404');
          } else if(error.status === 500){
              event.preventDefault();
              $state.go('500');
          }

      });
我找不到如何访问单元测试中的运行阶段?要对特定的侦听器进行单元测试? 我想测试是否调用了
$state.go


我将感谢您的帮助/建议-谢谢

如果您想测试Angular调用
$state.go()
,那么您正在编写一个集成测试,如果框架不支持这种类型的测试(我不确定它是否支持),这可能会很棘手

通常,为了解决此类问题,我会使用以下技巧:

  • 我测试函数,而不是侦听器
  • 我测试该函数是否在侦听器中正确注册
  • 在我向您描述它之前,请稍微改变一下您的想法,忘记这个匿名函数
    函数(事件、toState、toParams、fromState、fromsparams、error){…}
    并简单地将其命名为
    var myLogic=function(事件、toState、toParams、fromState、fromparms、error){…}
    你能看出区别吗?您不再有匿名回调,现在您有了自己的逻辑,必须对其进行测试

    现在,如果您专注于单元测试,那么您对测试Angular的侦听器机制是否按预期工作并不感兴趣。您要测试的是被触发的函数是否执行它需要执行的操作,即调用
    $state.go()
    。因此,既然您现在有了
    myLogic
    函数,那么现在就可以根据需要对其进行测试了

    // --------- Real class ---------
    var myLogic = function(component1, component2) {
       component1.do();
    }
    
    $rootScope.$on("event", myLogic);
    
    // --------- Tests pseudocode ---------
    
    // Test that your logic does what it is supposed to be doing
    
    // When
    myLogic(comp1Mock, comp2Mock);
    // Then
    expect(comp1.do).toHaveBeenCalled();
    
    // Test that your logic was attached to proper place in the framework. 
    // To do that, you have to mock part of the framework. Fortunately in 
    // Angular all parts of framework component/services are injected to 
    // a controller.
    
    // When - your controller is initialized
    // Then
    expect(rootScopeMock.on).toHaveBeenCalledWith("event", myLogic);
    

    有趣的想法,但我认为您在这个特定问题上有点过火,这正是我在测试中试图做的,但在运行阶段发生的逻辑方面我没有成功,在您的示例中,您建议在调用$rootScope.on时检查控制器的时间。我确实在上面加了一个西农间谍,但它不叫。。因为在真正的应用程序中,它被称为(并且正在工作),所以我假设这种行为与它“在”应用程序生命周期之外(在运行阶段,当应用程序启动时…)有关。如果我遗漏了什么,我会很高兴得到澄清