Testing Apollo GraphQL in your Angular application
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 withexpectOne
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 inafterEach
section to ensure that you calls don’t have a side effects. Similar toHttpTestingController.verify()
.