2.4.1 • Published 6 months ago

apollo-mocked v2.4.1

Weekly downloads
345
License
-
Repository
-
Last release
6 months ago

apollo-mocked

A mocked ApolloProvider solution that works equally well with Storybook and unit testing react components.

Install

npm install apollo-mocked or yarn add apollo-mocked

Features

Written in typescript, the apollo-mocked packages exposes 3 components for testing loading, error, and mocked data. All examples below will assume the following component:

import React from 'react';
import { useQuery } from '@apollo/client';
import gql from 'graphql-tag';

export const GET_DOG_QUERY = gql`
  query getDog($name: String) {
    dog(name: $name) {
      id
      name
      breed
    }
  }
`;

export interface DogComponentProps {
  name: string;
}

export const DogComponent: React.FC<DogComponentProps> = ({ name }) => {
  const { data, loading, error } = useQuery(GET_DOG_QUERY, { variables: name });

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;

  return (
    <p>
      {data.dog.name} is a {data.dog.breed}
    </p>
  );
};

Components

All components take an optional Provider prop which will generally default to the latest ApolloProvider from @apollo/react-hooks. If your using a different version you will probably need to pass an instance of ApolloProvider to each component.

ApolloLoadingProvider

propertypropTyperequireddefault
ProviderReact.ComponentType<any>no<ApolloProvider /> (@apollo/client v3.3.1)
testing example
import React from 'react';
import { screen } from '@testing-library/react';
import { ApolloLoadingProvider } from 'apollo-mocked';
import { DogComponent } from './';

describe('Dog', () => {
  it('should render loading component', async () => {
    const loadingText = 'Loading...';

    render(
      <ApolloLoadingProvider>
        <DogComponent name="Fido" />
      </ApolloLoadingProvider>
    );

    const loadingNode = await screen.queryByText(loadingText);
    expect(loadingNode).toBeInTheDocument();
    expect(loadingNode).toHaveTextContent(new RegExp(`^${loadingText}$`));
  });
});
storybook example
import React from 'react';
import { ApolloLoadingProvider } from 'apollo-mocked';
import { DogComponent } from './';

export default {
  title: 'Dogs',
  component: DogComponent,
};

export const Loading = () => (
  <ApolloLoadingProvider>
    <DogComponent name="Fido" />
  </ApolloLoadingProvider>
);

ApolloErrorProvider

propertypropTyperequireddefault
ProviderReact.ComponentType<any>no<ApolloProvider /> (@apollo/client v3.3.1)
errorMessagesstring or string[]no[new GraphQLError('Unspecified error from ErrorProvider.')]
testing example
import React from 'react';
import { render, screen } from '@testing-library/react';
import { ApolloErrorProvider } from 'apollo-mocked';
import { DogComponent } from './';

describe('Dog', () => {
  it('should render error component', async () => {
    const errorMessage = 'Failed to fetch dog.';

    render(
      <ApolloErrorProvider errorMessages={errorMessage}>
        <DogComponent name="Fido" />
      </ApolloErrorProvider>
    );

    await wait(() => {
      const errorNode = screen.getByText(errorMessage);
      expect(errorNode).toBeInTheDocument();
      expect(errorNode).toHaveTextContent(new RegExp(`^${errorMessage}$`));
    });
  });
});
storybook example
import React from 'react';
import { ApolloErrorProvider } from 'apollo-mocked';
import { DogComponent } from './';

export default {
  title: 'Dogs',
  component: DogComponent,
};

export const Error = () => (
  <ApolloErrorProvider>
    <DogComponent name="Fido" />
  </ApolloErrorProvider>
);

ApolloMockedProvider

propertypropTyperequireddefault
ProviderReact.ComponentType<any>no<ApolloProvider /> (@apollo/client v3.3.1)
addTypenamebooleannofalse
cacheOptionsInMemoryCacheConfigno--
clientOptionsApolloClientOptions<NormalizedCacheObject>no--
mocksReadonlyArray<MockedResponse> or LinkSchemaPropsyes--

linkSchemaProps

propertypropTyperequireddefault
introspectionResultIntrospectionQueryyes--
resolversIMocksyes--
typeResolversIResolversno--
mocks prop options
  • using the MockedResponse type
const mocks = [
  {
    request: {
      query: GET_DOG_QUERY,
      variables: {
        name: 'Fido',
      },
    },
    result: {
      data: {
        dog: { id: '1', name: 'Fido', breed: 'bulldog' },
      },
    },
  },
];
  • using the createMocks util (outputs MockedResponse[] like above)
import { createMocks } from 'apollo-mocked';
import { DOG_QUERY } from './dogQuery';

export const dogMocks = createMocks<DogQuery, DogQueryVariables>(DOG_QUERY, {
  data: {
    dog: { id: '1', name: 'Fido', breed: 'bulldog' },
  },
  variables: { name: 'Fido' },
});
  • using the IMocks type

Note: the typeDefs const below can also be a json file (result of introspecting schema)

const typeDefs = gql`
  type Query {
    hello: String
    resolved: String
  }
`;

const resolvers = {
  Query: {
    getDog: () => {
      id: '1',
      name: 'Fido',
      breed: 'bulldog'
    },
  },
};

const mocks = {
  introspectionResult: typeDefs,
  resolvers,
};
testing example
import React from 'react';
import { render, screen, wait } from '@testing-library/react';
import { ApolloMockedProvider } from 'apollo-mocked';
import { mocks } from './example-above';
import { DogComponent } from './';

describe('Dog', () => {
  it('should render the dog name', async () => {
    const dogName = 'Fido';

    render(
      <ApolloMockedProvider mocks={mocks}>
        <DogComponent name="Fido" />
      </ApolloErrorProvider>
    );

    await wait(() => {
      const dogNameNode = screen.getByText(dogName);
      expect(dogNameNode).toBeInTheDocument();
      expect(dogNameNode).toHaveTextContent(new RegExp(`^${dogName}$`));
    });
  });
});
storybook example
import React from 'react';
import { ApolloMockedProvider } from 'apollo-mocked';
import { mocks } from './example-above';
import { DogComponent } from './';

export default {
  title: 'Dogs',
  component: DogComponent,
};

export const DogName = () => (
  <ApolloMockedProvider mocks={mocks}>
    <DogComponent name="Fido" />
  </ApolloMockedProvider>
));
2.4.1

6 months ago

2.4.0

6 months ago

2.3.0

1 year ago

2.2.1

1 year ago

2.1.1

1 year ago

2.1.0

2 years ago

2.0.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.5.6

4 years ago

0.5.5

4 years ago

0.5.4

4 years ago

0.5.3

5 years ago

0.5.2

5 years ago

0.5.1

5 years ago

0.5.0

5 years ago

0.4.9

5 years ago

0.4.8

5 years ago

0.4.7

5 years ago

0.4.6

5 years ago

0.4.5

5 years ago

0.4.4

5 years ago

0.4.3

5 years ago

0.4.1

5 years ago

0.4.2

5 years ago

0.4.0

5 years ago

0.3.1

5 years ago

0.3.0

6 years ago

0.2.25

6 years ago

0.2.24

6 years ago

0.2.23

6 years ago

0.2.22

6 years ago

0.2.21

6 years ago

0.2.20

6 years ago

0.2.19

6 years ago

0.2.18

6 years ago

0.2.17

6 years ago

0.2.16

6 years ago

0.2.15

6 years ago

0.2.14

6 years ago

0.2.13

6 years ago

0.2.12

6 years ago

0.2.11

6 years ago

0.2.10

6 years ago

0.2.9

6 years ago

0.2.8

6 years ago

0.2.7

6 years ago

0.2.6

6 years ago

0.2.5

6 years ago

0.2.4

6 years ago

0.2.3

6 years ago

0.2.2

6 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.9

6 years ago

0.1.8

6 years ago

0.1.7

6 years ago

0.1.6

6 years ago

0.1.5

6 years ago

0.1.4

6 years ago

0.1.3

6 years ago

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago