javascript - Angular/Jasmine : spying on method passed to $rootScope. $on 带和不带匿名函数包装器

标签 javascript angularjs jasmine karma-jasmine

在 Angular 中,我在 $rootScope.$on 监听的事件被触发时调用一个方法。

$rootScope.$on('someEvent', some.method);

我正在监视我的 jasmine 测试中的方法,从我的测试中触发事件,然后检查是否调用了该方法。

spyOn(some, 'method');
$rootScope.$broadcast('someEvent');
expect(some.method).toHaveBeenCalled(); // fails

这个测试失败了。此外,该方法实际上已被调用(通过控制台日志验证)。

现在,我可以像这样将方法包装在一个匿名函数中:

$rootScope.$on('someEvent', function () { some.method(); });

测试通过。

spyOn(some, 'method');
$rootScope.$broadcast('someEvent');
expect(some.method).toHaveBeenCalled(); // passes

在这种情况下,实际上并没有调用方法本身(如预期的那样,因为它正在被监视)。

我已经设置了一套测试以在这个 Plunk 中充分说明:http://plnkr.co/edit/3S5J47OeCBsL0RASGe5P?p=preview

传递给 $rootScope.$on 的方法在事件触发时被调用,无论它是否包装在匿名函数中。然而, spy 只有在包裹在匿名函数中时才会注册。

在 jasmine 中,是否有可能成功地监视通过引用传递给 $rootScope.$on 的 Angular 函数。如果是这样,如何?如果不是,为什么不呢?

最佳答案

spyOn() 是一个突变体。 I forked your Plunk并添加了一些控制台日志。

考虑注册 spy 的调用:

spyOn(test, 'bar').andCallThrough();

这将创建一个新的 spy 函数,该函数执行 spy 工作,然后调用被 spy 函数。然后将 spy 存储在对象上以代替原始功能。在您的“无匿名包装器”示例中,您注册事件以调用 test.bar 的值在 spy 注册时:

$rootScope.$on('withoutFunctionWrapper', test.bar);

而对于包装器,事件将触发 test.bar 设置为在事件发生时,在您的情况下是 spy :

$rootScope.$on('withFunctionWrapper', function() {
  test.foo();
});

举例说明:

enter image description here

所以您可以先尝试调用 spyOn(),如果您正在监视的函数可以在调用 $rootScope.$on() 之前可用。否则,您将需要包装器。

关于javascript - Angular/Jasmine : spying on method passed to $rootScope. $on 带和不带匿名函数包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33550157/

相关文章:

javascript - 三JS : Using a Sprite with the OculusRiftEffect

javascript - 在页面加载时触发的 propertychange 事件

javascript - 'class'实例创建时的回调

javascript - 如何对多个表单元素使用指令

javascript - 通过多个复选框和属性问题进行 Angular 过滤

unit-testing - 如何使用 Jasmine 和 Webpack 运行 Typescript(不是 AngularJs)单元测试

javascript - RequireJS, $.Deferred 怎么办?

javascript - Angularjs 和 ui-router,在浏览器刷新时刷新所有父状态

Jasmine 测试期间变量中的正则表达式时javascript正则表达式测试()失败

javascript - Angular Testing - 找不到 test.ts