Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - unit test for a subscribe function in a component

Tags:

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);     });   })); }); 
like image 548
AngularM Avatar asked Aug 23 '17 12:08

AngularM


People also ask

How do I unit test a service with Angular components?

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.

What is tick () in Angular?

The tick() function simulates the asynchronous passage of time for the timers in the fakeAsync zone in Angular test.

What is fixture detectChanges ()?

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.


2 Answers

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'; 
like image 130
Sharikov Vladislav Avatar answered Sep 23 '22 19:09

Sharikov Vladislav


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();     });   })); 
like image 23
Pini Cheyni Avatar answered Sep 23 '22 19:09

Pini Cheyni