Angular 4 unit test for a subscribe.
I want to test that my subscribe returns an array of Users. I want to mock a list of users and test a function called getUsers.
The subscribe unit test doesnt work. Something wrong with the syntax.
This is my Users interface:
export interface User { id: number; name: string; username: string; email: string; address: { street: string; suite: string; city: string; zipcode: string; geo: { lat: string; lng: string; } }; phone: string; website: string; company: { name: string; catchPhrase: string; bs: string; }; };
This is my component I want to test:
import { Component, OnInit } from "@angular/core"; import { Observable } from "rxjs/Observable"; import { UserService } from "../../services/user.service"; import { User } from "../../models/user.model"; @Component({ selector: "home-users", templateUrl: "./home.component.html" }) export class HomeComponent implements OnInit { private listOfUsers: User[]; constructor(private userService: UserService) { } ngOnInit() { this.getUsers(); } getUsers(): void { this.userService.getUsers().subscribe(users => { this.listOfUsers = users; }); } }
This is my unit test attempt:
import { TestBed, async, inject } from "@angular/core/testing"; import { HttpModule } from "@angular/http"; import { HomeComponent } from "./home.component"; import { UserService } from "../../services/user.service"; import { User } from "../../models/user.model"; describe("HomeComponent", () => { let userService; let homeComponent; let fixture; let element; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ HomeComponent ], providers: [ UserService ], imports: [HttpModule] }).compileComponents(); })); beforeEach(inject([UserService], s => { userService = s; fixture = TestBed.createComponent(HomeComponent); homeComponent = fixture.componentInstance; element = fixture.nativeElement; })); it("should call getUsers and return list of users", async(() => { // Arrange let response: User[] = []; // Act homeComponent.getUsers(); fixture.detectChanges(); fixture.whenStable().subscribe(() => { expect(homeComponent.listOfUsers).toEqual(response); }); })); });
Mock Service Dependency In Angular For unit testing the method, you need to mock the service method getPosts to test the component method. Let's start by writing unit test for testing method getPostDetails when the response from service method getPosts is an empty array. Add the following unit test case to the app.
The tick() function simulates the asynchronous passage of time for the timers in the fakeAsync zone in Angular test.
fixture is a wrapper for our component's environment so we can control things like change detection. To trigger change detection we call the function fixture.detectChanges() , now we can update our test spec to: Copy it('login button hidden when the user is authenticated', () => { expect(el. nativeElement. textContent.
You need this for version rxjs@6
and above. For older rxjs
version answer is below:
import { of } from 'rxjs'; it("should call getUsers and return list of users", async(() => { const response: User[] = []; spyOn(userService, 'getUsers').and.returnValue(of(response)) homeComponent.getUsers(); fixture.detectChanges(); expect(homeComponent.listOfUsers).toEqual(response); }));
For old rxjs version change import from:
import { of } from 'rxjs';
to
import { of } from 'rxjs/observable/of';
I had similar issue and to make it work I used the arbitrary function (in the following code it's named done
) inside of it
it("should call getUsers and return list of users", async((done) => { // Arrange let response: User[] = []; // Act homeComponent.getUsers(); fixture.detectChanges(); fixture.whenStable().subscribe(() => { expect(homeComponent.listOfUsers).toEqual(response); done(); }); }));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With