Testing a service

The next example outlines how to test services. We want to test a service, which returns some countries from a remote backend:

@Injectable()
export class CountryService {
constructor(private http: Http) { }

getCountries(): Observable<Country[]> {
return this.http.get('/assets/data/countries.json')
.map(response => response.json().data as Country[]);
}
}

The Country objects have the following shape:

interface Country {
name: any;
dial_code?: any;
code?: any;
}

We don't want to make HTTP calls during the tests. To achieve that, we have to replace XHRBackend by MockBackend. The MockBackend allows us to catch outgoing HTTP requests and simulate incoming responses. We can just define a response as we want and then compare the result from the service with our expectations. The next code snippet shows how to build a mocked response, so when we finally make a call to our service, it gets the predefined array of countries:

import {TestBed, inject} from '@angular/core/testing';
import {HttpModule, XHRBackend, Response, ResponseOptions}
from '@angular/http';
import {MockBackend, MockConnection} from '@angular/http/testing';
import {CountryService} from './country.service';
import Country from './country';

describe('CountryService (MockBackend)', () => {
let mockbackend: MockBackend, service: CountryService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [CountryService, MockBackend,
{provide: XHRBackend, useClass: MockBackend}
]
})
});

beforeEach(inject([CountryService, MockBackend],
(cs: CountryService, mb: MockBackend) => {
service = cs;
mockbackend = mb;
}));

it('should return mocked response', () => {
let israel: Country = {'name': 'Israel',
'dial_code': '+972', 'code': 'IL'};
let angola: Country = {'name': 'Angola',
'dial_code': '+244', 'code': 'AO'};
let response = [israel, angola];

mockbackend.connections.subscribe((connection: MockConnection) => {
connection.mockRespond(new Response(new ResponseOptions({
status: 200, body: JSON.stringify(response)
})));
});

service.getCountries().subscribe(countries => {
expect(countries.length).toBe(2);
expect(countries).toContain(israel);
expect(countries).toContain(angola);
});
});
});

Note, that we don't need the async() function here because MockBackend behaves synchronously. Now, when all the tests are successful, you will see the following output:

The demonstrated test of the service class was not an isolated unit test. Isolated unit tests explore the inner logic of the tested class and don't require the Angular testing utilities. You don't need to prepare a testing module, call inject(), async(), and so on. A test instance of the class is created with new, supplying mock, spy, or fake objects for the constructor parameters. Generally, services and pipes are good candidates for isolated unit testing. Read the official Angular testing guide to learn more details (https://angular.io/docs/ts/latest/guide/testing.html).

The complete project with instructions is available on GitHub at
https://github.com/ova2/angular-development-with-primeng/tree/master/chapter10/unit-testing.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.12.50