DEV Community

Alejandro Estrada
Alejandro Estrada

Posted on

Testing GraphQL on the frontend and backend as well!

Making some test of your code is always a good practice that you should implement. The tests that you do will help you prevent some bugs and also it will ensure that your app work as you think it should work.

Sometimes making tests can be difficult and will require a lot of code, but most of the times it depends on the implementation that you’re using to test your code; there are packages that can help you make the tests with a few lines of code.

Today I'm going to use easygraphql-tester to show an option to test your GraphQL queries, mutation, and subscriptions on the frontend and backend as well.

easygraphql-tester can be used to mock queries, mutations, subscriptions; also, it can be used as an assertion and to test the resolvers.

Frontend testing.

If we want to test our GraphQL queries and mutations on the frontend we should follow the next steps:

  • Install the package: npm i -D easygraphql-tester -or- yarn add -D easygraphql-tester
  • On the package.json you can create a new script that will download the GraphQL schema from the server, something like this:
    • "prepare-schema": "npx get-graphql-schema <YOUR_SERVER_URL> > schema.json".
    • Before running the tests, run the script npm run prepare-schema to get the latest version of the GraphQL schema.
  • Install your favorite test runner.
  • Initialize the class, and pass the schema.

Used queries and mutations:

const CREATE_ITEM_MUTATION = gql`
  mutation CREATE_ITEM_MUTATION(
    $title: String!
    $description: String!
    $price: Int!
    $image: String
    $largeImage: String
  ) {
    createItem(
      title: $title
      description: $description
      price: $price
      image: $image
      largeImage: $largeImage
    ) {
      id
    }
  }
`;


const SINGLE_ORDER_QUERY = gql`
  query SINGLE_ORDER_QUERY($id: ID!) {
    order(id: $id) {
      id
      charge
      total
      createdAt
      user {
        id
      }
      items {
        id
        title
        description
        price
        image
        quantity
      }
    }
  }
`;

Example using Jest and easygraphql-tester - assertion.

'use strict'

import EasyGraphQLTester from 'easygraphql-tester';
import fs from 'fs';
import path from 'path';

import { CREATE_ITEM_MUTATION } from '../components/CreateItem';
import { SINGLE_ORDER_QUERY } from '../components/Order';

const schema = fs.readFileSync(path.join(__dirname, '..', 'schema.graphql'), 'utf8');

const tester = new EasyGraphQLTester(schema);

it('should pass CREATE_ITEM_MUTATION', () => {
  tester.test(true, CREATE_ITEM_MUTATION, {
    title: 'New item',
    description: 'This is going to be my new item',
    price: 10
  })
});

it('should pass SINGLE_ORDER_QUERY', () => {
  tester.test(true, SINGLE_ORDER_QUERY, { 
    id: '1' 
  })
});

Example using Jest and easygraphql-tester - mock:

You can use the mock method as well to test that your view render properly with expected data, you can set there some fixtures

'use strict'

import EasyGraphQLTester from 'easygraphql-tester';
import fs from 'fs';
import path from 'path';

import { CREATE_ITEM_MUTATION } from '../components/CreateItem';
import { SINGLE_ORDER_QUERY } from '../components/Order';

const schema = fs.readFileSync(path.join(__dirname, '..', 'schema.graphql'), 'utf8');

const tester = new EasyGraphQLTester(schema);

it('should pass CREATE_ITEM_MUTATION', () => {
  const variables = {
    title: 'New item',
    description: 'This is going to be my new item',
    price: 10
  };

  const result = tester.mock({
    query: CREATE_ITEM_MUTATION,
    variables
  });

  expect(typeof result.data.createItem.id).toBe('string');
});

it('should pass SINGLE_ORDER_QUERY', () => {
  const result = tester.mock({
    query: SINGLE_ORDER_QUERY,
    variables: {
      id: '1'
    },
    fixture: {
      data: {
        order: {
          id: '1',
          createdAt: '03-11-2019',
          items: [{
            id: '1234'
          }]
        }
      }
    }
  });

  expect(result.data.order.id).toBe('1');
  expect(result.data.order.createdAt).toBe('03-11-2019');
  expect(result.data.order.items[0].id).toBe('1234');
  expect(typeof result.data.order.total).toBe('number');
  expect(typeof result.data.order.items[0].description).toBe('string');
});

Backend testing:

If we want to test our GraphQL queries and mutations on the backend we should follow the next steps:

  • Install the package: npm i -D easygraphql-tester -or- yarn add -D easygraphql-tester
  • Install your favorite test runner and prepare the tests.
  • Initialize the class, and pass the schema.

Note:

  • If you are not using graphql-js, you might pass the resolvers as the second argument to the constructor in order to test the resolvers.

After you initialize the class, you can use the method graphql and it'll receive 4 arguments, the only one that is required is the first argument, those arguments are:

  • query: The query/mutation you want to test.
  • rootValue: It's going to be the rootValue to pass to the resolver.
  • contextValue: It's going to be the context to pass to the resolver.
  • variableValues: It's going to be the variables that the query/mutation are going to use.

Resolver

"use strict";

const license = (__, args, ctx) => {
  const { key } = args;

  return {
    id: "1234",
    body: "This is a test license",
    description: `This is a description with key ${key}`
  };
};

module.exports = {
  Query: {
    license
  }
};

Test using Jest.

"use strict";

const fs = require("fs");
const path = require("path");
const { expect } = require("chai");
const EasyGraphQLTester = require("easygraphql-tester");

const resolvers = require("../resolvers");
const schemaCode = fs.readFileSync(
  path.join(__dirname, "..", "schema.gql"),
  "utf8"
);

describe("Test resolvers", () => {
  let tester;
  beforeAll(() => {
    tester = new EasyGraphQLTester(schemaCode, resolvers);
  });

  it("should return expected values", async () => {
    const query = `
      query GET_LICENSE($key: String!) {
        license(key: $key) {
          id
          body
          description
        }
      }
    `;

    const args = {
      key: "1234"
    };

    const result = await tester.graphql(query, {}, {}, args);
    expect(result.data.license.id).to.be.eq("1234");
    expect(result.data.license.body).to.be.eq("This is a test license");
    expect(result.data.license.description).to.be.eq(
      `This is a description with key ${args.key}`
    );
  });
});

If you like this package don’t forget to give a ⭐️ on GitHub

Demo

Repo

Website

Top comments (0)