Testing Apollo GraphQL in your Angular application

Sergey Fetiskin
2 min readJun 28, 2018

--

Testing Apollo so far was very tricky, for us who are used to simplicity and richness of testing module from HttpClient. Thankfully, in the recent version (I’m talking about 1.1.0) we got a similar testing module to test our GraphQL queries.

So here is how to setup testing for your GraphQL services.

Import ApolloTestingController and ApolloTestingModule.

import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing';

Include testing module in your configuration and get reference to the testing controller.

let backend: ApolloTestingController;beforeEach(() => {
TestBed.configureTestingModule({
imports: [
ApolloTestingModule
]
...
});
});

beforeEach(() => {
...
backend = TestBed.get(ApolloTestingController);
});

So far, it’s very straightforward and looks very similar to Http client testing.

Now it’s time to write a test case. I’m testing a simple search service that has method search(term: string). This method execute search query and return me a list of found items as an Observable. The query looks like this

export const searchQuery = gql`
query search($term: String!) {
search(query: $term) {
edges {
node {
id
name
}
}
}
}
`;

We need to send some fake data to our search service from a fake backend. This might look like this.

const TEST_DATA: Search.Node[] = [
{
id: '1',
name: 'Apple',
}, {
id: '2',
name: 'Banana',
}
];

const TEST_SEARCH = {
'data': {
'search': {
'edges': [
{
node: TEST_DATA[0]
},
{
node: TEST_DATA[1]
}
]
}
}
};

Now we’re fully equipped to make a test case

it('should test search', (done) => {
service.search('test').subscribe(result => {
expect(result).toEqual(TEST_DATA);
done();
});

backend.expectOne(searchQuery).flush(TEST_SEARCH);
});

Update: Instead of providing whole document we can just use query name like .expectOne('searchQuery') .

Interesting details here. You have to use done callback, because this operation is asynchronous. I’m using Jasmine framework, for other frameworks it might be different. I expect only one request and send its data back with flush method.

The other options to react on incoming request are

  • networkError where we can simulate 404 or 401 errors.
  • graphqlError where we can send GraphQL errors object back.

Besides query object we can pass a function to expectOne method which accept Operation object. In this function you can check value of variables for example. If query matches return true from this function.

Other ApolloTestingController methods to match queries

  • match general matcher for incoming operations. The main difference with expectOne is it may return multiple operations and it doesn’t make any assertions how many times a query was performed.
  • expectNone to don’t expect specific operation. Also accepts function as a matcher.
  • verify checks that we don’t have outstanding connections. Normally, you call it in afterEach section to ensure that you calls don’t have a side effects. Similar to HttpTestingController.verify().

--

--