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



我有一些东西必须在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(),那么您正在编写一个集成测试,如果框架不支持这种类型的测试(我不确定它是否支持),这可能会很棘手。

通常为了解决这些问题,我使用以下技巧:

  1. 我测试的是函数,而不是监听器
  2. 我测试这个函数是否在侦听器中正确注册

在我向您描述它之前,请稍微改变一下您的想法,忘记这个匿名函数function(event, toState, toParams, fromState, fromParams, error){...},并简单地-命名它var myLogic = function (event, toState, toParams, fromState, fromParams, 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);

哇!

最新更新