$emit 上的单元测试间谍 [英] unit test spy on $emit

查看:37
本文介绍了$emit 上的单元测试间谍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从指令中窥探 $emit,但不知何故我无法让间谍听到"$emit.

I'm trying to spy on an $emit from a directive, but somehow I cannot get the spy to 'hear' the $emit.

这是我的指令的控制器中的代码:

This is the code in my directives' controller:

$scope.$on('send', function () {
    console.log('called');
    $scope.$emit('resultSend', {'ok': true, 'data': ''});
});

这是我的单元测试:

var $rootScope, $compile, elm, element;

beforeEach(inject(function ($injector) {
    $rootScope = $injector.get('$rootScope');
    $compile = $injector.get('$compile');
    elm = angular.element('<test></test>');
    element = $compile(elm)($rootScope);
}));


it('should listen for the send broadcast and emit the resultSend', function () {
    spyOn($rootScope, '$emit');
    $rootScope.$broadcast('send');
    expect($rootScope.$emit).toHaveBeenCalledWith('resultSend');
});

console.log 输出('调用')是由 Karma 打印出来的,所以我猜单元测试广播事件确实有效.

The console.log output ('called') is printed out by Karma, so I guess the unit test broadcast event does work.

这是否与 $emit 不是向下广播而是向上广播有关,如果是,我如何捕捉它,如果不是,我该如何处理这种情况?

Does this have to do with $emit not broadcasting down but up, and if so, how do I catch it, and if not, how else do I handle this case?

推荐答案

根据文档 这里,您对$emit$broadcast 之间区别的理解是正确的.但是,我认为问题在于您对 $scope$rootScope 的使用.您的 $rootScope 将位于范围层次结构的顶层.我猜测(仅通过查看您的代码段而无法看到所有代码)您的控制器中的 $scope 是一个嵌套控制器,这意味着 $scope在您的控制器中是应用程序 $rootScope 的子项.

According to the docs here, you are correct in your understanding of the difference between $emit and $broadcast. However, I think the problem is in your use of $scope and $rootScope. Your $rootScope will be at the top level of your scope hierarchy. I'm guessing (just by looking at your snippets without being able to see all the code) that your $scope in your controller is a nested controller, meaning that $scope in your controller is a child of the app's $rootScope.

因此,当您的单元测试监视 $rootScope.$emit 函数时,它实际上并没有监视控制器的 $scope.$emit()称呼.这两个范围"是不同的,不是一回事.因此,您需要模拟为控制器提供的 $scope,然后对其执行 spyOn.

Because of that, when your unit test spys on the $rootScope.$emit function, it is not actually spying on your controller's $scope.$emit() call. Those two "scopes" are different, not the same thing. So, you need to mock the $scope that you provide for the controller and then do a spyOn on that.

例如,在您的 beforeEach 中:

var ctrl, scope;

beforeEach(function() {
    module('<INSERT YOUR CONTROLLERS MODULE NAME HERE>'); 
    inject(function($rootScope, $controller) {
        scope = $rootScope.$new();
        ctrl = $controller('<CTRL NAME HERE>', {$scope: scope});
    });
});

这段代码实际上会创建一个模拟"范围变量,并将该对象提供给您的控制器,然后您可以使用它进行间谍和其他操作.如:

This code will actually create a "mock" scope variable and will provide that object to your controller, which you can then do spies and other things with. Such as:

spyOn(scope, '$emit');
// do whatever triggers the "$emit" call
expect(scope.$emit).toHaveBeenCalledWith('resultSend');

我很确定这应该可以解决您的问题.如果需要更多解释,请告诉我.

I'm pretty sure that should fix your problem. Let me know if that needs more explanation.

这篇关于$emit 上的单元测试间谍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆