Testing Angular services

In this section, we will learn how to test Angular dependency injection through services and interfaces. In order to test an Angular service, we will first need to create a service in our app!

Use the ng generate command in the Angular CLI; we will generate the service in the project folder:

ng generate service services/dealers

Upon successful execution, we should see that the following files have been created:

  • services/dealers.service.spec.ts
  • services/dealers.service.ts

Now that we have our dealers service and the corresponding test spec file generated, we will work on our service to add a few methods and variables, so we will use them in our test specs. Navigate to our service class and update the dealers.service.ts file. The updated code should look as follows:

import { Injectable } from '@angular/core';

@Injectable({
providedIn: 'root'
})
export class DealersService {
dealers: any;

constructor(private http : HttpClient) { }

getDealers(){
this.dealers = [
{ id: 1, name: 'North Auto'},
{ id: 2, name: 'South Auto'},
{ id: 3, name: 'East Auto'},
{ id: 4, name: 'West Auto'},
];

return this.dealers;
}

}

In the preceding code, we are making simple changes so that we can write a few test specs around the dealers service. We have defined a variable of the any type. We are defining a getDealers method, which will return a JSON response with an id and name key pair. Alright, now let's come up with some use cases to write our test scripts, such as getting the count of dealers, finding a matching dealer, and so on.

Use case #1: When the getDealers method is called, it should return the list of dealers, and the count should be equal to 4.

The following is the test spec for this:

it('Test Dependency Injection to get 4 dealers', () => {
const service: DealersService = TestBed.get(DealersService);
let dealers = service.getDealers();
expect(dealers.length).toBe(4);
});

Use case #2: We want to check whether the first dealer name is North Auto.

The following is the test spec for this:

it('Test if the first Dealer is North Auto', () => {
const service: DealersService = TestBed.get(DealersService);
let dealers = service.getDealers();
expect(dealers[0].name).toBe('North Auto');
});

Amazing! So far, so good. So, we have learned how to write test specs for our newly created dealers service. That's only one part of dependency injection. As part of dependency injection, we may need to inject additional required classes at runtime into the service. 

Let's quickly create a class called Dealers and define two variables in it, namely username and name. Now, let's save this file as dealers.ts:

export class Dealers {

constructor(
public username: string = '',
public name: string = ''
) {};

}

We will now include the newly created class in our dealers service and create a method to initialize the class and create an object to return some data:

getDealerObject()
{
this.dealerObj= new Dealers('World','Auto');
return this.dealerObj;
}

That brings us to our next use case to test.

Use case #3: Testing dependency injection via classes that have been injected into a service.

Have a look at the following code:

 it('Test if the dealer returned from object is World Auto', () => {
const service: DealersService = TestBed.get(DealersService);
let dealerObj = service.getDealerObject();
expect(dealerObj.name).toBe('Auto');
});

In the preceding code, we have created an instance of our service and invoked the getDealerObject() method. We are asserting whether the value returned matches the name property of the response to Auto.

We are calling the method defined in a service, which, internally, is dependent on the Dealers class.

Use case #4: What if we want to test just the properties of the Dealers class?

We can test that, too. The following is the sample code for this:


it('should return the correct properties', () => {
var dealer = new Dealers();
dealer.username = 'NorthWest';
dealer.name = 'Auto';

expect(dealer.username).toBe('NorthWest');
expect(dealer.name).toBe('Auto');

});

Now, let's run the ng test command. We should see the following output:

On the same lines, you can write test scripts to test your services, dependency classes, or interface classes.

Use case #5: Testing Angular services inside a component.

We will continue to test Angular dependency injection. This time, we will import our services into the component and verify that it's working as expected.

In order to implement this use case, we will need to make changes to AutoListComponent.

Take a look at the changes we will make in the auto-list.component.ts file:

import { DealersService } from '../services/dealers.service';
constructor(private _dealersService : DealersService) { }
findAuto() {
this.dealers = this._dealersService.getDealers();
return this.dealers;
}

In the preceding code, we are importing the dealers service into the component. We are creating an instance of the service in the constructor method. We added a findAuto method, which calls the getDealers method using the instance of the class _dealersService service. In order to test the service in our component, let's modify the auto-list.component.spec.ts file by adding the following code:

import { DealersService } from '../services/dealers.service';
beforeEach(() => {
fixture = TestBed.createComponent(AutoListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
service = TestBed.get(DealersService);
});

In the preceding code, we have imported our service dealers into the test spec file of AutoListComponent. We are creating an instance of the service using TestBed in the beforeEach method. We are now good to start writing our test specs in order to test the service. Add the following code to auto-list.component.spec.ts:

it('should click a button and call method findAuto', async(() => {
const fixture = TestBed.createComponent(AutoListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
spyOn(component, 'findAuto');
let dealers = component.findAuto();
expect(dealers.length).toEqual(4);

}));

In the preceding code, using the instance of the component, we are calling the findAuto method, which will return the data from the service. It expects the count to be equal to 4.

Run the tests using the ng test command. We should see the following output:

In this section, we learned about various techniques to test Angular dependency injection, including services, dependency classes, and testing services inside Angular components.

..................Content has been hidden....................

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