Angular Unit Testing BehaviorSubject | Karma | Jamsine


How to Unit Test Behavior Subject in Angular?

Let’s say you have a service file having a behavior subject.

import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {map, skipWhile, tap} from 'rxjs/operators'
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ServService {

  testName$: BehaviorSubject<any> = new BehaviorSubject<any>([]);

  constructor(private http : HttpClient) { }

  getData(){
    return this.http.get('https://jsonplaceholder.typicode.com/users')
      .pipe(
        map((response:any) => response.map(item => item['name']))
      )
  }
}

You are using the testName$ in your component’s getObs method as shown:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import {ServService} from '../app/serv.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  
  data;
  constructor(private service : ServService, private fb : FormBuilder){}

  ngOnInit(){
    this.getObs();
  }

  getObs(){
    this.service.testName$.subscribe((response) => {
      this.data = response;
    })
  }
 
}

So how to unit test the method getObs?

Here is how the unit test case looks like:

  it('should call getObs', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    const service = fixture.debugElement.injector.get(ServService);
    service.testName$.next("hello world");
    app.getObs();
    expect(app.data).toEqual("hello world");
  });

As seen in the above code, you first make a call to the getObs method to subscribe to the behavior subject. Then you need to trigger the behavior subject with a value and validate the same value in the data variable in component.