Angularjs 如何以角度测试事件?

Angularjs 如何以角度测试事件?,angularjs,unit-testing,angularjs-directive,jasmine,dom-events,Angularjs,Unit Testing,Angularjs Directive,Jasmine,Dom Events,我需要测试事件是否正确发射或广播,并手动触发事件 最好的方法是什么?如果您只是需要对事件触发和捕获进行一些测试,我就是这样做的。为了确保某个事件被触发($emit-ed或$broadcast-ed),间谍是一个不错的选择。您需要对将调用$emit或$broadcast的作用域的引用,然后执行以下操作: spyOn(scope, "$emit") //run code to test expect(scope.$emit).toHaveBeenCalledWith("MY_EVENT_ID", o

我需要测试事件是否正确发射或广播,并手动触发事件


最好的方法是什么?

如果您只是需要对事件触发和捕获进行一些测试,我就是这样做的。为了确保某个事件被触发(
$emit
-ed或
$broadcast
-ed),间谍是一个不错的选择。您需要对将调用
$emit
$broadcast
的作用域的引用,然后执行以下操作:

spyOn(scope, "$emit")
//run code to test
expect(scope.$emit).toHaveBeenCalledWith("MY_EVENT_ID", other, possible, args);
var eventEmitted = false;
$rootScope.$on("MY_EVENT_ID", function() {
   eventEmitted = true;
});
//run code to test
expect(eventEmitted).toBe(true);
如果您不需要或不想担心随
$emit
传递的参数,可以在
$rootScope
上放置一个
$on
,并设置一个标志以知道事件已发出。大概是这样的:

spyOn(scope, "$emit")
//run code to test
expect(scope.$emit).toHaveBeenCalledWith("MY_EVENT_ID", other, possible, args);
var eventEmitted = false;
$rootScope.$on("MY_EVENT_ID", function() {
   eventEmitted = true;
});
//run code to test
expect(eventEmitted).toBe(true);
对于在捕获事件时运行的测试功能(
$on
),它更容易一些。只需从
inject
函数获取
$rootScope
,然后发送所需的事件

$rootScope.$broadcast("EVENT_TO_TEST", other, possible, args);
//expects for event here
现在,我设想这个事件处理将发生在一个指令或一个控制器(或两者)中,用于设置指令测试,请参阅。有关设置控制器测试的信息,请参阅


希望这能有所帮助。

以下是在angular JS中创建$broadcast事件时应遵循的步骤

在注入时,初始化根范围和范围存根,如下所示:

var rootScope;
var scopeStub = beforeEach(function() {
    inject(function($rootScope, _$controller_) {
        rootScope = $rootScope;
        scopeStub = $rootScope.$new();
        $controller = _$controller_;
    });
});
创建控制器后,使用rootScope引发事件,如下所示:

rootScope.$broadcast('eventName', parameter1);

我们用这个sintax来表示A1

=========== Controller ========
    var vm = this;
    $scope.$on('myEvent', function(event, data){
        console.log('event number', data.id);
    });
============ Test =============
 it('should throw myEvent', function() {
    var data = {};
    $scope.$broadcast('myEvent', {id:1});
    $scope.$broadcast('myEvent', {id:2});
    $scope.$broadcast('myEvent', {id:3});
});

============ Output ============
Chrome LOG: '--------------------------------------------'
Chrome LOG: 'event number', 1
Chrome LOG: 'event number', 2
Chrome LOG: 'event number', 3

这对于精确匹配很好,但是如何匹配参数子集呢?例如,如果args只是一个对象{p1:'yes',p2:'no'},那么无论p2是什么(或者它是否存在),您如何期望p1:'yes'?我知道有“任何”茉莉花键盘,但似乎恰恰相反——控制不够精细。你能指望得到你想要的参数吗?@LukeMadera Jasmine拥有
Jasmine.objectContaining
。在文档中:jasmine.objectContaining适用于期望只关心实际对象中某些键/值对的情况。谢谢,但是有没有办法使用jasmine?类似于:
expect(scope.$emit.calls.argsFor(0)[0]).toBe('MY_EVENT_ID')
@dnc253我有一个父节点正在侦听
$emit
事件。只有当我使用
$rootScope.$broadcast
并检查事件时,我的测试才会通过,而
$rootScope.$emit
的测试则不会通过,这是因为
$emit
只能向上遍历节点,而不能遍历节点本身和子节点吗?@cameronjroe有点晚了,但我相信使用
来调用
是合适的,即使只是检查是否触发了事件。这是因为事件名称是
$emit
的一个参数,所以在这里测试是有意义的。