3
votes

How to write unit tests for graphql. I am using apollo server, graphql-tester, and graphql.

When i run the test it gives following error


    { raw: '{"errors":[{"message":"Cannot read property \'definitions\' of undefined"}]}',
      data: undefined,
      errors: [ { message: 'Cannot read property \'definitions\' of undefined' } ],
      headers: 
       { 'x-powered-by': 'Express',
         'content-type': 'application/json',
         date: 'Wed, 18 Jan 2017 05:56:22 GMT',
         connection: 'close',
         'transfer-encoding': 'chunked' },
      status: 400,
      success: false }
          1) Returns success


      0 passing (35ms)
      1 failing

      1) Unittest1 Returns success:
         TypeError: Cannot read property 'success' of undefined
          at Assertion. (node_modules/chai/lib/chai/core/assertions.js:890:14)
          at Assertion.ctx.(anonymous function) (node_modules/chai/lib/chai/utils/addMethod.js:41:25)
          at Assertion.somethingMethod (node_modules/chai-things/lib/chai-things.js:97:25)
          at Assertion.ctx.(anonymous function) (node_modules/chai/lib/chai/utils/overwriteMethod.js:49:33)
          at Assertion.allMethod (node_modules/chai-things/lib/chai-things.js:165:25)
          at Assertion.ctx.(anonymous function) (node_modules/chai/lib/chai/utils/overwriteMethod.js:49:33)
          at node_modules/chai-as-promised/lib/chai-as-promised.js:305:22
          at process._tickCallback (internal/process/next_tick.js:103:7)

Following is the unit test.


    const tester = require('graphql-tester').tester;
    const fromGlobalId = require('graphql-relay').fromGlobalId;

    const chai = require('chai');

    chai.should();
    chai.use(require('chai-things'));
    chai.use(require('chai-properties'));
    chai.use(require('chai-arrays'));
    chai.use(require('chai-as-promised'));

    describe('Sites', () => {
      let sitesTest = tester({
        url: 'http://localhost:3000/graphql'
      });

      describe('Unittest1', () => {
        const response = sitesTest('{viewer {id}}').then((data) => {
          console.log(data)
        });

        it('Returns success', () => {
          return response.should.eventually.have.property('success').equal(true);
        });

      });

    });

4
Same setup, getting the same error. Did you get this working?jschr
I moved to some other task, didn't get time to check again. Will check your below mentioned answer. Thanks for help..M Atif

4 Answers

5
votes

Here's how I got it working:

const gql = tester({
  server: createExpressWrapper(server),
  url: '/graphql',
  authorization: `Bearer ${token}`,
  contentType: 'application/json'
})

gql(JSON.stringify({ query: '{ users { id } }' })).then((data) => {

})

Apollo's graphql server expects the content type to be set to application/json with a payload of { query: "...", variables: {}}.

0
votes

Maybe you can use easygraphql-tester, using this package, you can test the queries/mutations/subscriptions against your schema. It can be used to return a mock or as assertion package, so in your case you can do something like this:

const EasyGraphQLTester = require('easygraphql-tester')

const tester = new EasyGraphQLTester(schema)
const query = `
  {
    viewer {
      id
    }
  }
`
const mock = tester.mock({ query })

Then you can test the result of the mock... or, you can set fixtures there as well!

0
votes

Not related to graphql-tester but an alternative for Apollo-Server. Maybe helpful.

I found it very comfortable writing integration tests using the apollo-server-testing. It will create a test-client for an apollo-server instance which requires no running server.

import { ApolloServer } from 'apollo-server';
import { createTestClient } from 'apollo-server-testing';

const prepareServer = async () => {
  // creating your real schema
  const schema = await Schemas.getSchemas();
  return new ApolloServer({
    schema,
    dataSources: () => ({
      data: new MockDatasource(), // provides mocked data
    }),
  });
};

it('test query', async () => {
  const server = await prepareServer();
  const { query } = createTestClient(server);

  const result = await query({ query: QUERY_GQL });
  // test result data
});

More detailed example on the apollo page: https://www.apollographql.com/docs/apollo-server/features/testing.html

-1
votes

Are you sure the GraphQL API is running? It is generally good practice to let the test suite handle spinning up the test server for you so you can run the tests without external dependencies. I pass in a wrapped express server along with a relative url to graphql-tester.

For example,

const expressApp = initApp();
const client = tester({
  server: createExpressWrapper(expressApp),
  url: '/graphql',
});

Assuming the initApp() does indeed return an express application that will run a GraphQL API at the /graphql endpoint, I believe it should work for you.

For reference, here is the implementation of createExpressWrapper. https://github.com/sazzer/graphql-tester/blob/master/src/main/servers/express.js