测试window.postMessage指令

时间:2015-06-19 13:35:48

标签: angularjs angularjs-directive jasmine

我在测试我的指令时遇到问题,该指令通过注册消息处理程序来启用跨文档消息传递:

.directive('messaging', function ($window, MyService) {
    return {
        link: function () {
            angular.element($window).on('message', MyService.handleMessage);
        }
    };
})

我想进行单元测试的是,当编译该指令并调用window.postMessage('message','*')时,应该调用我的消息处理程序:

http://jsfiddle.net/mhu23/L27wqn14/(包括茉莉花测试)

感谢您的帮助! 迈克尔

1 个答案:

答案 0 :(得分:1)

您使用的是原始window API,但您并未嘲笑它,因此方法postMessage将保持其异步行为。知道这一点,测试应该以异步方式编写。在JSFiddle中你有Jasmine 1.3,所以测试看起来应该是这样的:

it('should ....', function () {

    var done = false;

    spyOn(MyService,'handleMessage').andCallFake(function () {
        // set the flag, let Jasmine know when callback was called
        done = true; 
    });

    runs(function () {
        // trigger async call
        $window.postMessage('message','*');    
    });

    waitsFor(function () {
        // Jasmine waits until done becomes true i.e. when callback be called
        return done; 
    });

    runs(function () {
        expect(MyService.handleMessage).toHaveBeenCalled();
    });

});

检查docs about testing async with Jasmine 1.3。这是一个working JSFiddle

Jasmine 2.x

会更容易一些
it('should ....', function (done) {

    spyOn(MyService,'handleMessage').and.callFake(function () {
      expect(MyService.handleMessage).toHaveBeenCalled();
      done();
    });

    $window.postMessage('message','*');
});

另外,我必须提一下,你必须改变你从这个

添加一个监听器的方式
angular.element($window).on('message', MyService.handleMessage);

到那个

angular.element($window).on('message', function (e) {
    MyService.handleMessage(e);
});

因为.on注册了一个函数本身,所以它不会被用作附加到MyService的方法,所以你无法窥探它。