rxjs icon indicating copy to clipboard operation
rxjs copied to clipboard

throwError with a falsy value is not equal to undefined in Marble Testing with TestCheduler

Open hijiangtao opened this issue 5 years ago • 2 comments

Bug Report

Current Behavior

Marble testing with throwError(undefined) should return an Observable with *.notification.error equals to the value passed into throwError constructor itself, but it's expected to a default string called 'error' currently.

Expected $[0].notification.error = undefined to equal 'error'.

Reproduction

My function to be test shows here:

// util.ts

import { Observable, throwError } from 'rxjs';

const securedErrorHandler = (obj) => {
	return err => {
	    return throwError(obj);
	};
}

The unit test file shows:

// util.spec.ts

import { throwError } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { securedErrorHandler } from './util';

describe('securedErrorHandler', () => {
    const expectedMarbles = '#';

    let scheduler: TestScheduler;

    beforeEach(() => {
        scheduler = new TestScheduler((actual, expected) => {
            expect(actual).toEqual(expected);
        });
    });

	it('#securedErrorHandler should construct an error if input error is not an instance of Observable', () => {
	        scheduler.run(({ expectObservable }) => {
	            const result$ = securedErrorHandler(undefined);
	
	            expectObservable(result$).toBe(expectedMarbles, null, undefined);
	        });
	}
}

Expected behavior

Unit test should get passed.

Environment

  • Runtime: Latest Chrome
  • RxJS version: 6.5.3

Possible Solution

I found following logic in https://github.com/ReactiveX/rxjs/blob/fd66c2937ef73172d512f56b4c868e75a78635ab/src/internal/testing/TestScheduler.ts#L353

It will set error value to 'error' when passed in errorValue is a falsy value. Is there any consideration about it, I think it should be removed or be documented in RxJs docs.

hijiangtao avatar Jul 02 '20 07:07 hijiangtao

Arg!!!! Why is there no action on this in 3 years?

I just ran into this same issue. I am trying to write a test with TestScheduler for a method that does this subscriber.error(). My test is really simple expectObservable(observable).toBe('#')

This test fails with the following

    - Expected  - 1
    + Received  + 1

      Array [
        Object {
          "frame": 0,
          "notification": Object {
    -       "error": "error",
    +       "error": undefined,
            "kind": "E",
            "value": undefined,
          },
        },
      ]

I have tried using expectObservable(observable).toBe('#', undefined, 'error') but that doesn't work. What does work is if I modify my code to subscriber.error('error') which is completely unacceptable.

Am I missing something here? Why is the TestScheduler setting a default value?

andrewalderson avatar May 05 '23 22:05 andrewalderson

I have kinda the same issue, the workaround for me is the following:

expectObservable(wsConnector.messages()).toBe(
        expectMarbles,
        expectedValues,
        Error('my custom error message'),
      );

nichitaa avatar Jan 20 '24 21:01 nichitaa