AngularJS:如何在测试中调用事件处理程序和检测绑定

时间:2013-07-10 16:14:43

标签: unit-testing angularjs angularjs-directive angularjs-e2e

我想为各种自定义angularjs指令编写单元和e2e测试,这些指令将javascript事件绑定添加到它们所附加的元素中。

在测试中,使用jQuery方法模拟click和dblclick事件很容易。

element("#id").click();

但是,我也绑定了mouseover,mouseout和contextmenu事件,并且还没有找到在e2e测试中调用这些事件的方法。下面的代码显示了我正在采取的方法。

it('should show a context menu when the user right clicks on a grid row', 
    function () {
    //not currently triggering the context menu
    var outerRow = element(".ngRow", "outer row");
    var row = element(".ngRow:first > div", "row");
    angular.element(row).triggerHandler("contextmenu");
    expect(outerRow.attr("class")).toContain("open");
});

如何在测试中触发contextmenu事件?

类似地,在指令的单元测试中,我希望能够检测是否已将事件绑定附加到元素。

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:4)

最终了解到这一点。要在使用jQuery选择的元素上触发事件,显然需要加载jQuery。问题在于,正如here所解释的那样,Angular运行器在没有加载jQuery的IFrame中运行测试。

但是,您可以扩展角度方案dsl,以便在加载jQuery的e2e测试的上下文中执行代码。下面的函数允许您执行任何javascript方法,或者触发任何事件:

//this function extends the Angular Scenario DSL to enable JQuery functions in e2e tests
angular.scenario.dsl('jqFunction', function () {
    return function (selector, functionName /*, args */) {
        var args = Array.prototype.slice.call(arguments, 2);
        return this.addFutureAction(functionName, function ($window, $document, done) {
            var $ = $window.$; // jQuery inside the iframe
            var elem = $(selector);
            if (!elem.length) {
                return done('Selector ' + selector + ' did not match any elements.');
            }
            done(null, elem[functionName].apply(elem, args));
        });
    };
}); 

以下代码使用上述函数在e2e测试中触发contextmenu事件:

it('should show a context menu when the user right clicks on a grid row', function () {
    var outerRow = element(".ngRow:first", "outer row");
    jqFunction(".ngRow:first > div", "contextmenu");
    expect(outerRow.attr("class")).toContain("open");
});