API Call Testing in Angular 2

I have the following 2 components and one service that is shared by both. I need to unit test them, but I cannot figure out how to test the dependency of the service on the following components.

//a.component.ts
import { Component, Input } from '@angular/core';
import { Http, Response } from '@angular/http';
import { SharedService } from './shared/shared.service';

@Component({
  selector: 'a',
  providers: [],
  templateUrl: './a.component.html'
})
export class AComponent {
  ax = {};

  constructor(public helperService: SharedService) {
    helperService.getFromAPI().subscribe(data => this.ax = data["people"]);
  }

}



//b.component.ts
import { Component } from '@angular/core';
import { SharedService } from './shared/shared.service';
import { Subscription }   from 'rxjs/Subscription';


@Component({
  selector: 'b',
  providers: [],
  templateUrl: './b.component.html'
})

export class BComponent {
  subscription: Subscription;
  x = '';

  constructor(public helperService: SharedService) {}

  ngOnInit() {
    this.subscription = this.helperService.c$.subscribe(
      data => {
        this.x = data;
      });
  }
}

      

This is the service that calls the API. Another function setC

adds a value to the observable when the button is pressed, and that value must be accessible using BComponent

.

// shared.service
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/map';

@Injectable()
export class SharedService {

  private c = new Subject<string>();
  c$ = this.c.asObservable();

  constructor(
    private http: Http
  ) { }

  getFromAPI() {
    return this.http.get('url')
      .map((res: Response) => res.json());
  }

  setC(data: string) {
    this.c.next(data);
  }
}

      

How can I check this in Jasmine? So far, my efforts have been futile.

I've tried doing like

it('xxx', inject([SharedService], (service: SharedService) => {
    const fixture = TestBed.createComponent(AComponent);
    const app = fixture.componentInstance;

    spyOn(service, 'c$').and.callThrough;

    service.setC('Random Name');
    expect(service.c$).toHaveBeenCalled();

  }));

      

This cannot be verified with Expected spy c$ to have been called.

.

+3


source to share


1 answer


You follow Observable

, it looks like, but the callable when you call setC

is a function of next

your object. As such, you probably want to keep an eye on this.

Something like spyOn(service.c, 'next').and.callThrough()

should do the trick.

Hope it helps.




Update. If you want to explicitly test the functionality of yours Observable

, I'll just subscribe to it, call setC

and test the answer, something like this:

service.$c.subscribe((data) => {
    expect(data).toBe('foobar');
});
service.setC('foobar');

      




To answer your question in the comments: because your c

is kept private, you can monitor it as follows: spyOn(service['c'], 'next').and.callThrough()

. Perhaps your ideal would start spying on private methods, in which case you can add a type any

like this:spyOn<any>(...)

+3


source







All Articles