0

How can I do a simple angular Jasmine Unit testing when using RXJS reactive approach

Here is my simple implementation of the component. I have an items stream that gets some collection of items. Then I have a dropdown in HTML that calls the onSelectItem method which triggers the next() method of the selectedItemSubject. My goal is to test the $itemsWithSelected stream - to check if it returns the correct value - which is influenced by the selected Item and the items stream.

  items$ = this.someService.getItems().pipe(
    map((items) => {
      return items;
    })
  );

  private selectedItemSubject$ = new Subject<any>();
  selectionItemAction$ = selectedItemSubject$.asObservable();

  $itemsWithSelected = combineLatest([this.selectionItemAction$, items$]).pipe(
    map(([selected, items]) => {
      var targetItem = items.find(x => x.id === selected);
    return someProcess(targetItem.someProperyOfThisItem);
    }));

  //some method that calls next of the subject
  onSelectItem($event){
    this.selectedItemSubject$.next($event.value);
  }
Gani Lastra
  • 245
  • 1
  • 14

2 Answers2

0

To check a value, emitted by $itemsWithSelected, you can chain a pipe and tap the emitted value:

$itemsWithSelected = combineLatest([this.selectionItemAction$, items$])
        .pipe(
            tap(([selected, items]) => {
                // check the emitted value here
                if (selected === 'SOME_PREDEFINED_VALUE' && items === 'SOME_OTHER_PREDEFINED_ITEM') {
                    // do this and that
                }
            }),
            map(([selected, items]) => {
                var targetItem = items.find(x => x.id === selected);
                return someProcess(targetItem.someProperyOfThisItem);
            })
        );

You can also put a tap on the $itemsWithSelected observable itself, like so:

    $itemsWithSelected
        .pipe(
            tap((value: TheTypeReturnedFromSomeProcessFunction) => {
                // check the emitted value here
                if (value === 'SOME_PREDEFINED_VALUE') {
                    // do this and that
                }
            })
        );

note that after map, the values emitted by the stream would be of the type returned by the someProcess which is unclear from the code (I marked it as TheTypeReturnedFromSomeProcessFunction)

Lorraine R.
  • 1,545
  • 1
  • 14
  • 39
  • Thanks, But I am looking for writing the UNIT tests in jasmine for this bit. Will update the question for clarity – Gani Lastra Mar 14 '22 at 13:14
0

Here is how I did this ->

it('should have correct items per selected',
    fakeAsync(() => {
      component.items$.subscribe(x => {
        expect(x.length).toBe(2); // some value
      });
      tick(200);
       
      component.onSelectItem({ value: { id: 1 } });

      tick(200);

      component.$itemsWithSelected.subscribe(items => {
        expect(items.length).toBe(2);
        expect(items[0].name).toBe("someName");
      });

      flush();
    }));
Gani Lastra
  • 245
  • 1
  • 14