Using MockBackend to test Susper Angular Front-end Code

In this blog, I’ll be sharing how we are testing services which we are using in Susper development.We’re using Angular 4 in our project as tech stack and we use Jasmine for testing purpose.

Tests are written to avoid issues which occur again and again. For example: Since we have implemented knowledge graph, we faced a lot of issues like:

  • When a user enters a query, search results appear but knowledge graph does not appear.
  • When a fresh query is entered or page is refreshed, knowledge graph does not appear.
  • The API which we have used is not responding.

We overcome this issue by writing test. The data is being taken with the help of an API. So, it will require testing using HTTP. Instead of testing like this, there is a better way by using MockBackend.

Testing with MockBackend is a more sensible approach. This allows us to mock our responses and avoid hitting the actual backend which results in boosting our testing.

To use the MockBackend feature, it requires creating a mock. For knowledge-service it looks like this:

export const MockKnowledgeApi {
  results: {
    uri: ‘http://dbpedia.org/resource/Berlin’,
    label: ‘Berlin’,
  }
  MaxHits: 5
};

To use the MockBackend feature, import MockBackend, MockConnection, BaseRequestOptions and MockKnowledgeApi.

import { MockBackend, MockConnection } from ‘@angular/http/testing’;
import { MockKnowledgeApi } from ‘./shared/mock-backend/knowledge.mock’;
import { BaseRequestOptions } from ‘@angular/http’;

Create a mock setup. In this case, we will create mock setup w.r.t HTTP because data from API is being returned as HTTP. If data, is being returned in JSON format, create a mock setup w.r.t jsonp.

const mockHttp_provider = {
  provide: Http,
  deps: [MockBackend, BaseRequestOptions],
  useFactory: (backend: MockBackend,options: BaseRequestOptions) => {
    return new Http(backend, options);
}
};

Now, describe the test suite. Inside, describe the function, don’t import MockConnection. It will throw error since it is only used to create a fake backend. It should look like this:

providers: [
  KnowledgeapiService,
  MockBackend,
  BaseRequestOptions,
  mockHttp_provider,
]
Define service as KnowledgeService and backend as MockBackend. Inject both the services in beforeEach() function.
Now to actually test the service, create a query.

const searchquery = ‘Berlin’;

The written specs should look like this. I won’t go much in detail here, but I’ll cover up the key points of code.

it(‘should call knowledge service API and return the result’, () => {
backend.connections.subscribe((connection: MockConnection) => {
const options = new ResponseOptions({
body: JSON.stringify(MockKnowledgeApi)
});connection.mockRespond(new Response(options));
expect(connection.request.method).toEqual(RequestMethod.Get);
});
Here, mockRespond will mock our response and it will test whether the service is working or not. Already, we have defined a query.

It should have a link to API and should be equal to searchquery which we have defined already as ‘Berlin’.

expect(connection.request.url).toBe(
`http://lookup.dbpedia.org/api/search/KeywordSearch` +
`?&QueryString=${searchquery}`
);

At last, it will check if it’s working or not. If it’s working, then test case will pass. Please note, it will not hit the actual backend.

service.getsearchresults(searchquery).subscribe((res) => {
expect(res).toEqual(MockKnowledgeApi);
);
In this way, we have written tests for knowledge graph to avoid future issues. We will be adding tests like these for other services as well which are being used in Susper project.

Resources