我进行了以下测试
it('should send message to window...', inject(
[AppEventsService],
(service: AppEventsService) => {
spyOn(window.parent, 'postMessage').and.callThrough();
service.sendMessage('MyTestEvent', 'empty');
expect(window.parent.postMessage).toHaveBeenCalledWith(
JSON.stringify({ e: 'MyTestEvent', v: 'empty' }),
'*'
);
}
));
这适用于Chrome,但在IE浏览器中我得到了
Error: <toHaveBeenCalledWith> : Expected a spy, but got Function.
Usage: expect(<spyObj>).toHaveBeenCalledWith(...arguments)
但为什么?使用中的方法执行以下操作
public sendMessage(event: string, param: string) {
const message = {};
message['e'] = event;
if (StringUtils.isNullOrWhiteSpace(param)) {
message['v'] = '';
} else {
message['v'] = param;
}
window.parent.postMessage(JSON.stringify(message), '*');
}
问题是在IE 11中,postMessage
方法的propertyDescriptor被标记为不可写且不可配置。因此,在IE 11上,您无法覆盖该属性。
这里最好的方法是将windows.parent.postMessage
方法包装在自定义方法中,如下所示:
function postToParent(...args) {
return window.parent.postMessage(...args);
}
然后用window.parent.postMessage
替换所有对postToParent
的调用。
最后,在您的测试中,执行:
spyOn(window, 'postToParent').and.callThrough();