0
votes

I wrote a test for the following method:

  private _segmentationStatus$: Subject<string> = new Subject();
  public readonly segmentationStatus: Observable<string> = this._segmentationStatus$.asObservable();

  /**
   * Get the status from the segmentation service.
   */
  public getStatus() {
    const segmentationId: string = this._segmentationIdService.segmentationId;
    const segmentationStatusUrl = `${this.getSegmentationStatusUrl}/${segmentationId}/status`;
    this._http
      .get(segmentationStatusUrl, { responseType: 'text' })
      .subscribe({
        next: () => {
          this._loggerService.trackTrace(`Segmentation status: ${status}`, LogSeverity.Verbose);
          this._segmentationStatus$.next(status);
        },
        error: (error) => {
          this._messageService.emitMessage(new Message(MessageCode.ErrorGetStatus, error));
          this._loggerService.trackException(error);
          this._segmentationStatus$.error(error);
        }
      });
  }

To test the method I started to write a test as below:

    fit('should emit a message if the request failed', done => {
      let messageReceived: Message;
      spyOn((service as any)._messageService, 'emitMessage').and.callFake(message => {
        messageReceived = message;
      });
      service.segmentationStatus.subscribe({
        error: () => {
          expect(messageReceived.messageCode).toBe(MessageCode.ErrorGetStatus);
          done();
        }
      });
      spyOnProperty(
        (service as any)._segmentationIdService,
        'segmentationId',
        'get'
      ).and.returnValue('id');

      service.getStatus();

      httpTestingController
        .expectOne(`${service.getSegmentationStatusUrl}/id/status`)
        .flush('{}', { status: 500, statusText: 'status' });
    });

If I use the debugger the flow of the program and test is as expected. I see the emitted message and the error handler in the unit test is called. However, after the error handler in the unit test completes the line this._segmentationStatus$.error(error); in the productive code throws another error, which is not handled. Thus the tests fails with the message Uncaught [object Object] thrown.

I`ve read the RxJS documentation and googled the problem, but was not able to figure out what I need to do pass the test. Any help to point out where I did the mistake would be highly appreciated.

1
I've found the problem; there was another subscriber to segmentationStatus which did not handle the error. As nobody "trapped" the exception it bubbled up and was re-thrown. As explained in On The Subject Of Subjects (in RxJS).Patrik Gfeller

1 Answers

0
votes

I've found the problem; there was another subscriber to segmentationStatus which did not handle the error. As nobody "trapped" the exception it bubbled up and was re-thrown. As explained in On The Subject Of Subjects (in RxJS).