0

I'm fairly new to Angular4 and need to write unit tests for a simple services I've built, but don't know where to start.

The service simply wraps an api call as follows:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/map';

import { KeyValuePair } from '../../models/keyvaluepair';
import { environment } from './../../../environments/environment';

// Lookups api wrapper class.
@Injectable()
export class LookupsService {

    private servicegApiUrl = '';

    public constructor( private http : HttpClient ) {  
        // Build the service api url, uring the environment lookups api url, plus controller name to reference.
        this.servicegApiUrl = environment.webApiUrl + 'Lookups/';
    }

    // Get the hubs from the web api.
    public getHubs() :  Observable<KeyValuePair<number>[]> {
        // Carry out http get and map the result to the KeyValuePair number object.
        return this.http.get<KeyValuePair<number>[]>(this.servicegApiUrl + 'Hubs').map(res => { return res; });
    }
}

I need to test my getHubs() method and dont know how. Also, I've seen various articles online about testing a service and I'm not sure if I've to mock the results expected or if this should actually call the web service. I have this code, but the expect never seems to get executed:

import { TestBed, async, inject } from '@angular/core/testing';
import { HttpClientModule, HttpRequest, HttpParams } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { LookupsService } from './Lookups.Service';
import { KeyValuePair } from './../../models/KeyValuePair';

describe(`LookupsService tests`, () => {

  beforeEach(() => {

    TestBed.configureTestingModule({
      imports: [
        HttpClientModule,
        HttpClientTestingModule
      ],
      providers: [
        LookupsService
      ]
    });
  });



  it(`should get results from the web method`, async(inject( [ LookupsService, HttpTestingController ],

    (service: LookupsService, backend: HttpTestingController) => {

      service.getHubs().subscribe((hubs : KeyValuePair<number>[]) => {
        // This code never seems to run...
        console.log(hubs.length);
        expect(hubs.length).toBeGreaterThan(0);
      });
  })));

});

For completeness KeyValuePair class looks like this:

export class KeyValuePair<T> {
    Key : string;
    Value : T;
}

Any help much appreciated!

Rob
  • 6,819
  • 17
  • 71
  • 131

1 Answers1

0

Unit test are supposed to (at least in most cases) test your code without the usage of real API or database calls.

One way to do this is to mock the libraries/dependencies/parts of code that is used for handling real data.

In your case, you could create a FakeHttpClient service, that would handle your fake data, and use it when you test your LookupService service. Initialization would go something like this:

var lookupService = new LookupService(new FakeHttpClientService());
//rest of your code for testing LookupService class.

You can find more details here.

Emin Laletovic
  • 4,084
  • 1
  • 13
  • 22
  • Ok cool - so best to test when not dependant on the real api. So I've mocking to do of the actual calls. Has anyone any good examples of testing a service with HttpClient as a dependency with mocked results? – Rob Oct 17 '17 at 12:38
  • You can always try to use `spyOn` to spy on a method. Check this SO answer for usage: https://stackoverflow.com/questions/30658525/spy-on-a-service-method-call-using-jasmine-spies – Emin Laletovic Oct 17 '17 at 12:54