测试服务是否对DOM事件做出反应

时间:2013-04-14 18:42:14

标签: javascript angularjs jasmine

我刚刚编写此服务以在关闭窗口时提醒用户他们是未保存的数据:

    module.factory('autosaver',
        ['$rootScope', '$window', 'editor', 'doc', 'saveInterval', '$timeout',
        function ($rootScope, $window, editor, doc, saveInterval, $timeout) {

        var scope = $rootScope.$new(true);
        scope.doc = doc;
        scope.confirmOnLeave = function(e) {
        var msg = "You have unsaved data.";

        // For IE and Firefox
        e = e || window.event;
        if (e) {e.returnValue = msg;}

        // For Chrome and Safari
        return msg;
    };
    scope.$watch('doc.dirty', function (newValue, oldValue) {
        if(newValue !== oldValue) {
            newValue ? $window.addEventListener('beforeunload', scope.confirmOnLeave) : $window.removeEventListener('beforeunload', scope.confirmOnLeave);
        }
    });

    return scope;
}]);

现在我想编写规范。我无法弄清楚如何模拟beforeunload事件并监视调用。 我试过这段代码:

    it('should listen to beforeunload event', inject(function ($window, autosaver) {
        autosaver.confirmOnLeave = jasmine.createSpy('confirmOnLeave');

        var evt = document.createEvent("beforeunloadEvents");
        evt.initMouseEvent("beforeunload", true, true, $window,
            0, 0, 0, 0, 0, false, false, false, false, 0, null);

        $window.dispatchEvent(evt);
    }));

但是我收到了这个错误:

NotSupportedError: NotSupportedError: DOM Exception 9
    Error: The implementation did not support the requested type of object or operation.

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

而不是直接使用DOM来模拟$window.addEventListener并立即调用回调函数。

jasmine.spyOn($window, 'addEventListener');

调用你的函数,然后触发事件:

var msg = $window.addEventListener.mostRecentCall. args[1]({}) 
expect(msg).toBeEqual("You have unsaved data.")