您正在使用原始的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 的方法,所以你将无法窥探它。