Apollo Server Unit testing using Jest & nock.

Gopal Saini
3 min readSep 11, 2020

--

When I went through the documentation in Apollo Server for Testing approach, I feel there could be a better way to do the same & I decided to utilize nock for mocking RestDataSource response.

Here, I will walkthrough to configure Apollo Server along with nock.

Before move to actual implementation, let’s have a quick overview of Apollo Server & nock…

Apollo Server is an open-source, spec-compliant GraphQL server that’s compatible with any GraphQL client, including Apollo Client. It’s the best way to build a production-ready, self-documenting GraphQL API that can use data from any source.

We can use Apollo Server as:

A stand-alone GraphQL server, including in a serverless environment

An add-on to your application’s existing Node.js middleware (such as Express or Fastify)

Here it’s a setup example how to create Apollo Test Server…

// test-utils/apollo-server.tsimport {
ApolloServer
} from 'apollo-server';
import {
createTestClient
} from 'apollo-server-testing';
import schema from '../schema'; /
import dataSources from '../services';
const createApolloTestServer = () => {
const server = new ApolloServer({
schema,
dataSources,
debug: true,
context: () => {
return {
token: 'foo'
};
}
});
return server;
};
const apolloServer = createApolloTestServer();export const {
query,
mutate
} = createTestClient(apolloServer);

nock

Well, there are a number of cool things about nock, just to mention a few…

HTTP server mocking and expectations library for node.js

Nock can be used to test modules that perform HTTP requests in isolation.

Why nock? & how does it work?

Nock works by overriding Node’s http.request method. Also, it overrides http.ClientRequest too to cover for modules that use it directly.

Let’s see an example, how nock can help to return mock responses…

// modules/todo/__test__/todos.spec.tsimport nock from 'nock';
import {
query as useQuery
} from './../../../test-utils/apollo-server';
import {
GET_TODOS
} from './gql';
import todos from './../../../mocks/todos.json';
describe('Todos Module', () => {
it('should return todos', async () => {
nock('https://jsonplaceholder.typicode.com')
.get('/todos')
.reply(200, todos);
const response = await useQuery({
query: GET_TODOS
});
expect(response).toMatchSnapshot();
});
});

Nock can help on the same way to perform testing on RESTDatasource as well…

// services/todo/__test__/todos.spec.tsimport nock from 'nock';
import {
initialize
} from './../../../test-utils/setup';
import {
TodosAPI
} from '../index';
import todos from './../../../mocks/todos.json';
describe('Todos RESTDatasource', () => {
let todosAPI: TodosAPI;
beforeAll(() => {
todosAPI = initialize(TodosAPI); // manual..
});
it('should return todos', async () => {
nock('https://jsonplaceholder.typicode.com')
.get('/todos')
.reply(200, todos);
const response = await todosAPI.getTodos();
expect(response).toMatchSnapshot();
});
});

In actual, we are not spying any method/function in between as it’s mentioned here. You can find the complete source code here on this github repository.

Conclusion

By using nock along with Apollo Server, we can better manage test mocks by intercepting HTTP Requests in isolation.

In all cases, single source of mocking/expectations would be always nock. When we talk about single source of mocking & performing test on a module in isolation, it enables the ways for integration testing to verify the actual dataSource/API response as well as Apollo Server query/mutation.

Thanks for reading this article! Please leave a comment below if you have any questions & feel free to provide feedback to improve.

--

--