如何在 Jasmine 中模拟 rxjs webSocket?

How to mock rxjs webSocket in Jasmine?

这是我的聊天服务:

import {webSocket, WebSocketSubject} from 'rxjs/webSocket';
import {delayWhen, retryWhen, take} from 'rxjs/operators';
import {timer} from 'rxjs';

...

export class ChatConnectionService {

  private readonly _connection: WebSocketSubject<any>;
  public readonly messages$: Observable<ChatInboundMessage>;

  constructor() {
    this._connection = this.getConnection();
    this.messages$ = this._connection.asObservable();
  }

  private getConnection(): WebSocketSubject<any> {
    return webSocket(`.../chat`);
  }

}

这是我目前尝试过的方法:

import * as rxJsWebSocket from 'rxjs/webSocket';

describe('ChatConnectionService', () => {
  let service: ChatConnectionService;

  const subject = new Subject();
  let webSocketSpy;

  beforeEach(() => {   
    webSocketSpy = spyOnProperty(rxJsWebSocket, 'webSocket', 'get').and.returnValue(<any>subject);

    service = new ChatConnectionService();
  });

  it('should create a new connection when service instantiated', () => {
    expect(webSocketSpy).toHaveBeenCalledTimes(1);
  });
});

但是它给我以下错误:

 Error: <spyOnProperty> : webSocket is not declared configurable

如何用主题替换 webSocket 以便我可以测试它? RxJs:6.5.5

似乎没有好的解决方案,这里有一个关于 fromEvent 运算符的类似主题: Error: <spyOn> : fromEvent is not declared writable or has no setter.

如果打算直接监视运营商,那么唯一可行的选择似乎是瞄准 ES5,我认为这不是解决方案,因为已部署的 ES6+ 可能减少包大小。

我想最好的选择可能是为 webSocket 运算符设置一个包装函数。包装函数已经可以被窥探了。在您的示例中,最简单的方法是为 getConnection() 函数设置一个间谍,该函数负责返回连接实例。