Unit Testing socket.io in Angular

Я пытаюсь выполнить единый тест угловой службы в моем приложении, которое создает клиент socket.io. Моя служба выглядит примерно так:

export class SocketService {
  private name: string;
  private host: string = window.location.protocol + "//" + window.location.hostname + ":3000";
  socket: io.Socket;

  constructor() { }

  subscribeEvent(name: string): Observable<IJobResp> {
    this.setup(name);
    return new Observable(observer => {
      this.socket.on('job', val => observer.next(val))
    })
  }

  private setup(name: string) {
    this.name = name;
    let socketUrl = this.host + "/" + this.name;
    this.socket = io.connect(socketUrl);
  }
}

Поэтому, чтобы написать мой тест, я использую библиотеку mock-socket для настройки mock socket.io-сервера. Вот как выглядит тест:

describe('SocketService', () => {
  let socket;

  const mockServer = new Server('http://localhost:3000/');
  mockServer.on('connection', server => {
    mockServer.emit('job', 'test message 1');
  });

  (window as any).io = SocketIO;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [JobService]
    });
  });

  it('should xyz, inject([JobService], fakeAsync((service: JobService) => {
    service.subscribeEvent('/').subscribe(val => {
      expect(val).toEqual('test message 1');
    })
  })));
});

Однако этот тест выдает ошибку:

Ошибка. Невозможно сделать XHR внутри фальшивого асинхронного теста.

Если у меня нет fakeAsync, тест проходит до того, как будет обработано утверждение в subscribe().

Как мне обойти это?

Обновить:

Другой подход, который я попытался использовать, - использовать async например

  it('should subscribe to dwnTime events', async(inject([JobService], (service: JobService) => {
    service.subscribeEvent('line/602').subscribe(val => {
      expect(val).toEqual('test 2');
    })
  })));

Затем я получаю:

Ошибка: Тайм-аут - обратный вызов Async не вызывается в течение таймаута, указанного jasmine.DEFAULT_TIMEOUT_INTERVAL.

Это похоже на проблему с синхронизацией, но я все еще не уверен, почему?

Ответ 1

Ваш второй подход является правильным, поскольку макет-сервер является реальным, поэтому вам нужно увеличить таймаут, установив

jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; (значение должно быть скорректировано)

где-нибудь внутри описательной функции.

Здесь вы можете найти полный пример.