Testing a GraphQL server using jest and graphql-tester

My programming experience without writing tests

I’ve been writing code for years without writing tests believing I was doing fine and it was not big of a deal to bother writing tests for my code.

When it comes to GraphQL I just got to the \graphiql url in my server, start writing my queries and mutations and test them myself and I was living my life as a happy coder worrying about nothing admiring how cool it is graphiql .

So, lets talk about my motivation to start writing tests for my code. It was just plain old curiosity.

Looking at many repositories on github and many node modules, I’ve found that almost all of them have this tests folder and tests for their code.

So, I thought why not give it a try and then I started.

My approach

Well I am new to testing but I think for testing an API the best way is by testing the http endpoint send requests to it and test the result so that we can test how everything is working together.

So I will be using this great package that does this task

And I will be using this Repo on Github that I’ve created for managing various user tasks via GraphQL, I’ve built it doing my plain old way without adding tests.

So, lets walk through adding tests to this code.

The Jest setup

First, Install jest and graphql-tester

yarn add jest graphql-tester --dev

And add test task to our package.json

"test": "jest"

Then we start with a simple test file describing what a user should do.

File: tests/index.test.js — test files are required to match this file name pattern **.test.js to be tested by default

describe('A user', function() {
it('should register with new user', () => {
expect(true).toBe(true);
});
it('should not register with existing user data', () => {
expect(true).toBe(true);
});
it('should not login with wrong credentials', () => {
expect(true).toBe(true);
});
it('should login with correct credentials', () => {
expect(true).toBe(true);
});
it('should not login twice', () => {
expect(true).toBe(true);
});
it('should logout after logging in', () => {
expect(true).toBe(true);
});
it('should not logout if not logged in', () => {
expect(true).toBe(true);
});
it('should removed by ID', () => {
expect(true).toBe(true);
});
});

You may note that every test describing a user has a callback function that validates the test.

Here we supplied every test with dummy validation — expecting true to equal true — using Jest’s expect. For more details check Jest’s Docs here

Then we run our test command from terminal

yarn test

and the result will be like this:

test result

Now lets setup real tests for our GraphQL endpoint using GraphQL tester.

Adding GraphQL tester

So, first we will need to hook up the test suite with the tester object before running any test.

This will be done using the beforeAll hook from jest.

describe('A user', function() {
const self = this;
beforeAll(() => {
self.test = tester({
url: `http://127.0.0.1:${config.APP_PORT}/${config.GQL_URL_DIR}`,
contentType: 'application/json'
});
});
});
contentType has to ‘application/json’ in case of using apollo express server

And with a real GraphQL test will look like this :

it('should register a new user', done => {
self
.test(
JSON.stringify({
query: `mutation register($username: String!, $password: String!) {
register(username: $username, password: $password) {
username
message
id
}
}`,
variables: {
username: 'test',
password: 'test'
}
}),
{ jar: true } // using my fork shalkam/graphql-tester to be able to add this option to the node request
)
.then(res => {
self.tempID = res.data.register.id; // adding userid to the test suite object
expect(res.status).toBe(200);
expect(res.success).toBe(true);
done();
})
.catch(err => {
expect(err).toBe(null);
done();
});
});
The tester just runs a simple node request and returns a promise with the results.

Complete test file can be found here.

then if we run tests by writing this in terminal:

yarn test

This will be the result

test results

And this it :) I’ve been able to add tests successfully to my code

All this work can be found in this repo

You can refer to it to see the full implementation.