0

Im having a problem writing unit tests for observable in Angular... Im trying to test cases if displayPaymentsLineItem$ will be true or false depending on the values of mobileAccountBalance$, and selectedMobileDigitalBill$... Can anyone help?

  public selectedMobileDigitalBill$: Observable<MobileDigitalBill>;
  public mobileAccountBalance$: Observable<MobileAccountBalance>;

  private expandedLinesMap: object = {};
  private expandedTaxesAndFees: boolean = false;
  private devices: MobileDevice[] = [];
  private destroy$: Subject<void> = new Subject();

  constructor(]
    private mobileStatementsTabFacade: MobileStatementsTabFacade,
    private billingMobileFacade: BillingMobileFacade,
  ) {}

  ngOnInit() {
        this.mobileAccountBalance$ = this.mobileStatementsTabFacade.mobileAccountBalance$;

        this.displayPaymentsLineItem$ = combineLatest([
          this.mobileAccountBalance$,
          this.selectedMobileDigitalBill$,
        ]).pipe(
          map(([mobileAccountBalance, selectedMobileDigitalBill]: [MobileAccountBalance, MobileDigitalBill]) => {
            const isPastDue: boolean = mobileAccountBalance?.pastdue > 0;
            const hasPayments: boolean = selectedMobileDigitalBill?.payments?.length > 0;

            return isPastDue && hasPayments;
          })
        );
      }
    });
protein
  • 37
  • 3

1 Answers1

0

You can take(1) (take one value, then complete) and subscribe to test if the emitted value is falsy. Observables need to be completed if you test them this way.

describe('The display payment line items observable', () => {
  it('should emit truthy', () => {
    displayPaymentsLineItem$
    .pipe(take(1))
    .subscribe(value =>{
      expect(value).toBeTruthy();
    });
  }
}

That being said, displayPaymentsLineItem$ won't emit anything if the two observables inside combineLatest() aren't defined in your test. Since they come from two facades, they may need to be provided before starting your test.

Also, about your code example:

  1. displayPaymentsLineItem$ isn't declared before the constructor.
  2. selectedMobileDigitalBill$ is declared but is never defined before it is referenced inside combineLatest().
Joshua McCarthy
  • 1,739
  • 1
  • 9
  • 6
  • The code also isn't a `class`.. :-). I think he has given a partial snapshot. – Nalin Ranjan Feb 03 '22 at 05:08
  • How would i add the two observables in combineLatest into the test? Sorry for basic quetions... im new to testing – protein Feb 03 '22 at 05:25
  • In that case, you can refer to Angular's article about testing basics for your component. They also detail how to setup mock services (which may be what you need to setup those observables.) https://angular.io/guide/testing-components-basics#component-class-testing – Joshua McCarthy Feb 03 '22 at 05:41