Spoiler Alert: the below is relating to integration testing and is not in TypeScript but I thought it might help OP or others looking to test thoroughly their data sources.
Now for the answer:
You can get inspiration from Apollo
's excellent full stack tutorial repo . It helped me a lot. Here is a sample where you can see they mocked the response from the launchAPI
and userAPI
data sources.
it('books trips', async () => {
const {server, launchAPI, userAPI} = constructTestServer({
context: () => ({user: {id: 1, email: 'a@a.a'}}),
});
// mock the underlying fetches
launchAPI.get = jest.fn();
// look up the launches from the launch API
launchAPI.get
.mockReturnValueOnce([mockLaunchResponse])
.mockReturnValueOnce([{...mockLaunchResponse, flight_number: 2}]);
// book the trip in the store
userAPI.store = mockStore;
userAPI.store.trips.findOrCreate
.mockReturnValueOnce([{get: () => ({launchId: 1})}])
.mockReturnValueOnce([{get: () => ({launchId: 2})}]);
// check if user is booked
userAPI.store.trips.findAll.mockReturnValue([{}]);
const res = await server.executeOperation({
query: BOOK_TRIPS,
variables: {launchIds: ['1', '2']},
});
expect(res).toMatchSnapshot();
});
And here is their constructTestServer
function.
const constructTestServer = ({ context = defaultContext } = {}) => {
const userAPI = new UserAPI({ store });
const launchAPI = new LaunchAPI();
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => ({ userAPI, launchAPI }),
context,
});
return { server, userAPI, launchAPI };
};
module.exports.constructTestServer = constructTestServer;
Here is a more simple example I setup for a plain get request on the data source I called randomUserApi
.
it('randomUser > should return expected values', async () => {
const randomUserApi = new RandomUserApi();
const server = new ApolloServer({
schema,
dataSources: () => ({ randomUserApi }),
});
const mockResponse = {
results: [
{
email: 'jordi.ferrer@example.com',
},
],
info: {
seed: '54a56fbcbaf2d311',
},
};
randomUserApi.get = jest.fn();
randomUserApi.get.mockReturnValueOnce(mockResponse);
const query = `query Query {
randomUser {
results {
email
}
info {
seed
}
}
}`;
// run query against the server and snapshot the output
const response = await server.executeOperation({
query,
});
const { data, errors } = response;
expect(errors).toBeUndefined();
expect(data).toEqual({
randomUser: {
info: { seed: '54a56fbcbaf2d311' },
results: [{ email: 'jordi.ferrer@example.com' }],
},
});
});
This is the code for RandomUserApi
:
const { RESTDataSource } = require('apollo-datasource-rest');
class RandomUserApi extends RESTDataSource {
constructor() {
// Always call super()
super();
// Sets the base URL for the REST API
this.baseURL = 'https://randomuser.me/';
}
async getUser() {
// Sends a GET request to the specified endpoint
return this.get('api/');
}
}
module.exports = RandomUserApi;
And the resolver using it
Query: {
randomUser: async (_parent, _args, context) => context.dataSources.randomUserApi.getUser(),
}
Full disclosure: same response posted here