【问题标题】:spyOn $scope.$on after $broadcast toHaveBeenCalled failsspyOn $scope.$on 在 $broadcast toHaveBeenCalled 失败后
【发布时间】:2014-08-16 04:50:21
【问题描述】:

我在进行这个简单的测试时遇到了很多麻烦。

我要测试的控制器中有一个$scope.$on 侦听器。我只是想确定它是在广播事件之后调用的。

为此,我认为以下代码会起作用:

describe("Testing the parent controller: ", function() {
    var scope, ctrl;

    beforeEach(function() {
        module("myApp");

        inject(function($rootScope, $controller) {
            scope = $rootScope.$new();

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


    it ("should trigger broadcast when current page updates", function() {
        spyOn(scope, "$on");
        scope.$broadcast("myEvent", 999);
        expect(scope.$on).toHaveBeenCalled();
    });
});

它没有 (Expected spy $on to have been called.)。我已经挖掘了很多例子:

学到了很多,但出于某种原因,我只是没有建立一些关键的联系。

我注意到$on 处理程序确实在断言后做出响应,这是无益的。我在各种配置中尝试过scope.$apply().andCallThrough(),但似乎没有任何效果。

这是怎么做到的?

【问题讨论】:

  • 你不应该在你的范围内调用 $digest() 吗?

标签: angularjs unit-testing events angularjs-scope jasmine


【解决方案1】:

在广播事件时,执行的是注册到$on 的侦听器函数,而不是$on 函数本身。

您当前的测试适用于这样的代码,这可能不是您所拥有的:

$scope.$on('myEvent', function () {
    $scope.$on('whatever', someFn);
});

您应该测试的是您注册的侦听器函数正在做什么。

如果你有:

$scope.$on('myEvent', function() {
  myFactory.doSomething();
});

像这样测试它:

spyOn(myFactory, "doSomething");
scope.$broadcast("myEvent");

expect(myFactory.doSomething).toHaveBeenCalled();

【讨论】:

  • 它认为scope.$digest()$broadcast 之后仍然需要。
  • 不是让监听器函数运行,但你是对的,它可能需要,这取决于监听器中的代码做什么。
  • 感谢@tasseKATT 周六早上 6 点起床试一试 :)
  • ...我们取得了突破。您的示例准确、简短、清晰。谢谢!
猜你喜欢
  • 2014-12-30
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多