In this tutorial, we will see how to write the unit test cases for Apollo Client – GraphQL in angular components. Also, we will cover the following points in this tutorial
Topics
Install Jest
First will install the Jest and jest-preset-angular package in our angular application.
npm install --save-dev jest jest-preset-angular
Setup Jest In Angular
Configure your jest setup with your suitable options, you can find more options over here https://jestjs.io/docs/en/cli
{
"name": "Apollo Client – GraphQL Testing In Angular Component",
"version": "0.0.1",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "jest --watch --coverage",
"e2e": "ng e2e"
},
"jest": {
"preset": "jest-preset-angular",
"setupTestFrameworkScriptFile": "<rootDir>/src/setupJest.ts"
},
}
setupTestFrameworkScriptFile
sets /src/setupJest.ts", so in that file we have to just import the jest-angular-preset package from node_module.
import 'jest-preset-angular';
Set GraphQL Query
For API call we will separate the GraphQL query as if we have multiple GraphQL for your application module. Instead of writing the GraphQL inside the component class, we will write all our GraphQL queries in module/graphql/query.ts
export const dummyApi = `
mutation Dummy(
$input: dummyInput,
) {
respondOrder(input : $input){
id
dummyData
join_id
}
}
`;
Create Service Methods With Apollo Client
Now we will create a service for our component in which the GraphQL will be imported and we return the Apollo method, so we can subscribe in the component class.
import { Injectable } from '@angular/core';
import { map, take } from 'rxjs/operators';
import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';
import { dummyApi } from '../graphql/query';
@Injectable()
export class DummyService {
constructor(private apollo: Apollo) {}
dummyMethod(input: any) {
return this.apollo
.watchQuery<any>({
query: gql(dummyApi),
variables: { input },
fetchPolicy: 'network-only'
})
.valueChanges.pipe(
map(result => result.data), // data in response
take(1) // call only once
);
}
}
Subscribe API In Component
After creating the api method we will inject the service in our component and subscribe the data to the variable declared in the component.
Let’s get into the code
import { Component, OnInit, Input } from '@angular/core';
import { DummyService } from '../../services/dummy.service';
@Component({
selector: 'app-dummy',
templateUrl: './dummmy.component.html',
styleUrls: ['./dummy.component.scss']
})
export class DummyComponent implements OnInit {
dummyData: Array<Object>;
constructor( private dummyService: DummyService){}
ngOnInit(){
this.callDummyAPI();
}
callDummyAPI(){
const input :any = {} // Any Inputs
this.dummyService.dummyMethod)(input).subscribe(
(res: any) => {
this.dummyData = res;
}, error => {
console.log(error);
});
}
}
Test Cases For Apollo API
After implementing the API will finally jump into the jest unit test cases for the same component.
- So first will create the dummy.component.spec.ts file in which our test suit will be implemented.
- After that, we will import all the required testing module and the module which are been used in the component module and the service for the component.
- And after that will write our test suit for method
callDummyAPI
So let’s get into it.
First thing first, let’s start with importing the required module and controller for testing Apollo Client – GrapgQL API and for the component.
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
// Apollo Testing Module And Controller
import { ApolloTestingModule, ApolloTestingController } from 'apollo-angular/testing';
import { OrdersService } from '../../services/dummy.service';
import gql from 'graphql-tag';
// GraphQL query
import { dummyApi } from '../../graphql/query';
After that will describe our test case which will contain our test suit and the variables to b used for testing the component methods.
...
describe('DummyComponent', () => {
let component: OrdersRespondComponent;
let fixture: ComponentFixture<OrdersRespondComponent>;
let route: MockActivatedRoute;
let controller: ApolloTestingController;
...
}
After that we will import the module, declare the component and provide the services which have been used in the component. also we spyOn
on our component from which API call is made.
...
describe('DummyComponent', () => {
...
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
...
ApolloTestingModule,
],
declarations: [
...,
DummyComponent
],
providers: [
...
DummyService
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(OrdersRespondComponent);
component = fixture.componentInstance;
fixture.detectChanges();
spyOn(component,'callDummyAPI').and.callThrough();
});
...
}
Now will write the test suit for the component, so first will check that component should be defined, and then will test the API method using mock API response data.
...
describe('DummyComponent', () => {
...
it('should load component ', () => {
expect(component).toBeDefined();
});
it('Should call the method and bind the API response to the defined variable', () => {
controller = TestBed.get(ApolloTestingController);
// mention the GraphQL query
const op = controller.expectOne(gql(dummyApi));
// Mock the response data
op.flush({
data: [
{
id:123,
...
},
{
id:124,
...
},
{
id:125,
...
}
]
});
expect(component.dummyData).toBeDefined();
... // other expectations
controller.verify();
});
}
Same way to cover the error part you can mock the error response data in op.flush
and write the expect component.dummyData
to be undefined.