简体   繁体   中英

How to do a simple angular Jasmine Unit testing when using RXJS reactive approach using a subject and a stream that calls a service

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);
  }

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 )

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();
    }));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM