How to Unit Test Behavior Subject in Angular?
{% include youtube_embed.html id=“Ae0wTmD_WkQ” %}
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.