How can I trigger a GraphQL error to test an ErrorLink on Apollo Client?

Viewed 1365

I have the following ErrorLink set for Apollo Client.

export const errorLink = onError(
  ({ response, graphQLErrors, networkError, operation }: ErrorResponse) => {
    notificationService.notify("An Error Occurred");
  },
);

I need to test this implementation in a unit test. I've the following to test Apollo Links

const MockQuery = gql`
  query {
    foo
  }
`;

interface LinkResult<T> {
  operation: Operation;
  result: FetchResult<T>;
}

async function executeLink<T = ApolloLink>(
  linkToTest: ApolloLink,
  request: GraphQLRequest = { query: MockQuery },
) {
  const linkResult = {} as LinkResult<T>;

  return new Promise<LinkResult<T>>((resolve, reject) => {
    execute(ApolloLink.from([linkToTest]), request).subscribe(
      (result) => {
        linkResult.result = result as FetchResult<T>;
      },
      (error) => {
        reject(error);
      },
      () => {
        resolve(linkResult);
      },
    );
  });
}

it('triggers a notification on error', () => {
  const testLink = new ApolloLink(() => {
    await waitFor(() => expect(notificationSpy).toBeCalledWith('An Error Occurred'))

    return null;
  });

  const link = ApolloLink.from([errorLink, testLink]);
  executeLink(link);
});

These unit test work fine for other links like AuthLink where I test whether the auth token was set to the localStorage. But I cannot test the error link because I cannot trigger a GraphQL error.

1 Answers

You can create a mocked terminating link and provide a GraphQL operation result.

E.g.

errorLink.ts:

import { onError } from '@apollo/client/link/error';

type ErrorResponse = any;

export const errorLink = onError(({ response, graphQLErrors, networkError, operation }: ErrorResponse) => {
  console.log('An Error Occurred');
  console.log('graphQLErrors: ', graphQLErrors);
});

errorLink.test.ts:

import { ApolloLink, execute, Observable } from '@apollo/client';
import { gql } from 'apollo-server-express';
import { errorLink } from './errorLink';

const MockQuery = gql`
  query {
    foo
  }
`;

describe('68629868', () => {
  test('should pass', (done) => {
    expect.assertions(1);
    const mockLink = new ApolloLink((operation) =>
      Observable.of({
        errors: [
          {
            message: 'resolver blew up',
          },
        ],
      } as any),
    );

    const link = errorLink.concat(mockLink);
    execute(link, { query: MockQuery }).subscribe((result) => {
      expect(result.errors![0].message).toBe('resolver blew up');
      done();
    });
  });
});

test result:

 PASS   apollo-graphql-tutorial  src/stackoverflow/68629868/errorLink.test.ts (5.02s)
  68629868
    ✓ should pass (14ms)

  console.log src/stackoverflow/68629868/errorLink.ts:6
    An Error Occurred

  console.log src/stackoverflow/68629868/errorLink.ts:7
    graphQLErrors:  [ { message: 'resolver blew up' } ]

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.067s

package version: @apollo/client@3.3.20

Related