or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

components.mdhoc.mdhooks.mdindex.mdssr.mdtesting.md
tile.json

testing.mddocs/

React Apollo Testing

React Apollo testing utilities provide mocking capabilities and testing helpers for GraphQL-powered React applications with comprehensive mocking and assertion tools.

Capabilities

MockedProvider

Test provider component that mocks GraphQL operations for isolated component testing.

/**
 * Provider component for mocking GraphQL operations in tests
 * @param props - Configuration for mocked GraphQL responses
 * @returns React provider element for testing
 */
function MockedProvider<TSerializedCache = {}>(
  props: MockedProviderProps<TSerializedCache>
): React.ReactElement;

interface MockedProviderProps<TSerializedCache = {}> {
  mocks?: ReadonlyArray<MockedResponse>;
  addTypename?: boolean;
  defaultOptions?: DefaultOptions;
  cache?: ApolloCache<TSerializedCache>;
  resolvers?: Resolvers;
  childProps?: object;
  children?: React.ReactElement;
  link?: ApolloLink;
}

interface MockedResponse {
  request: GraphQLRequest;
  result?: FetchResult | ResultFunction<FetchResult>;
  error?: Error;
  delay?: number;
  newData?: ResultFunction<FetchResult>;
}

Usage Examples:

import React from "react";
import { render, waitFor } from "@testing-library/react";
import { MockedProvider } from "react-apollo";
import { UserProfile } from "./UserProfile";
import { GET_USER_QUERY } from "./queries";

describe("UserProfile", () => {
  it("displays user information", async () => {
    const mocks = [
      {
        request: {
          query: GET_USER_QUERY,
          variables: { id: "1" }
        },
        result: {
          data: {
            user: {
              id: "1",
              name: "John Doe",
              email: "john@example.com",
              __typename: "User"
            }
          }
        }
      }
    ];

    const { getByText } = render(
      <MockedProvider mocks={mocks} addTypename={false}>
        <UserProfile userId="1" />
      </MockedProvider>
    );

    // Wait for query to resolve
    await waitFor(() => {
      expect(getByText("John Doe")).toBeInTheDocument();
      expect(getByText("john@example.com")).toBeInTheDocument();
    });
  });

  it("handles loading state", () => {
    const mocks = [
      {
        request: {
          query: GET_USER_QUERY,
          variables: { id: "1" }
        },
        result: {
          data: {
            user: {
              id: "1",
              name: "John Doe",
              email: "john@example.com"
            }
          }
        },
        delay: 1000 // Simulate slow network
      }
    ];

    const { getByText } = render(
      <MockedProvider mocks={mocks}>
        <UserProfile userId="1" />
      </MockedProvider>
    );

    expect(getByText("Loading...")).toBeInTheDocument();
  });

  it("handles error state", async () => {
    const mocks = [
      {
        request: {
          query: GET_USER_QUERY,
          variables: { id: "1" }
        },
        error: new Error("Failed to fetch user")
      }
    ];

    const { getByText } = render(
      <MockedProvider mocks={mocks}>
        <UserProfile userId="1" />
      </MockedProvider>
    );

    await waitFor(() => {
      expect(getByText("Error: Failed to fetch user")).toBeInTheDocument();
    });
  });
});

MockLink

Creates a mock Apollo Link for testing GraphQL operations with configurable responses.

/**
 * Create mock Apollo Link for testing
 * @param mocks - Array of mocked responses
 * @param addTypename - Whether to add __typename to responses
 * @returns Apollo Link for testing
 */
function MockLink(
  mocks: ReadonlyArray<MockedResponse>, 
  addTypename?: boolean
): ApolloLink;

/**
 * Create mock link with single operation
 * @param mockedResponses - Individual mocked responses
 * @returns Apollo Link for testing
 */
function mockSingleLink(...mockedResponses: MockedResponse[]): ApolloLink;

Usage Examples:

import { MockLink } from "react-apollo";
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";

describe("Apollo Client with MockLink", () => {
  it("executes queries with mocked responses", async () => {
    const mocks = [
      {
        request: {
          query: GET_USERS_QUERY,
          variables: { limit: 10 }
        },
        result: {
          data: {
            users: [
              { id: "1", name: "Alice", __typename: "User" },
              { id: "2", name: "Bob", __typename: "User" }
            ]
          }
        }
      }
    ];

    const mockLink = new MockLink(mocks, true);
    const client = new ApolloClient({
      link: mockLink,
      cache: new InMemoryCache()
    });

    const result = await client.query({
      query: GET_USERS_QUERY,
      variables: { limit: 10 }
    });

    expect(result.data.users).toHaveLength(2);
    expect(result.data.users[0].name).toBe("Alice");
  });

  it("handles mutation testing", async () => {
    const CREATE_USER_MUTATION = gql`
      mutation CreateUser($input: UserInput!) {
        createUser(input: $input) {
          id
          name
          email
        }
      }
    `;

    const mockLink = mockSingleLink({
      request: {
        query: CREATE_USER_MUTATION,
        variables: {
          input: { name: "Charlie", email: "charlie@example.com" }
        }
      },
      result: {
        data: {
          createUser: {
            id: "3",
            name: "Charlie",
            email: "charlie@example.com",
            __typename: "User"
          }
        }
      }
    });

    const client = new ApolloClient({
      link: mockLink,
      cache: new InMemoryCache()
    });

    const result = await client.mutate({
      mutation: CREATE_USER_MUTATION,
      variables: {
        input: { name: "Charlie", email: "charlie@example.com" }
      }
    });

    expect(result.data.createUser.name).toBe("Charlie");
  });
});

MockSubscriptionLink

Creates mock Apollo Link specifically for testing GraphQL subscriptions.

/**
 * Create mock subscription link for testing real-time operations
 * @returns Apollo Link for subscription testing
 */
function MockSubscriptionLink(): ApolloLink;

/**
 * Create mock observable link for testing
 * @returns Apollo Link for observable testing
 */
function mockObservableLink(): ApolloLink;

Usage Examples:

import { MockSubscriptionLink } from "react-apollo";
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";

describe("Subscription testing", () => {
  it("handles subscription data", (done) => {
    const COMMENT_SUBSCRIPTION = gql`
      subscription OnCommentAdded($postId: ID!) {
        commentAdded(postId: $postId) {
          id
          content
          author {
            name
          }
        }
      }
    `;

    const mockLink = new MockSubscriptionLink();
    const client = new ApolloClient({
      link: mockLink,
      cache: new InMemoryCache()
    });

    // Subscribe to updates
    const subscription = client.subscribe({
      query: COMMENT_SUBSCRIPTION,
      variables: { postId: "1" }
    }).subscribe({
      next: (result) => {
        expect(result.data.commentAdded.content).toBe("Test comment");
        done();
      },
      error: done
    });

    // Simulate subscription data
    mockLink.simulateResult({
      result: {
        data: {
          commentAdded: {
            id: "1",
            content: "Test comment",
            author: { name: "Test User" },
            __typename: "Comment"
          }
        }
      }
    });
  });
});

Testing Helper Functions

Utility functions for testing GraphQL applications.

/**
 * Create Apollo Client instance for testing
 * @param config - Optional client configuration
 * @returns Configured Apollo Client for tests
 */
function createClient(config?: any): ApolloClient<any>;

/**
 * Remove Apollo-specific symbols from data for testing
 * @param data - Data object to clean
 * @returns Data without Apollo symbols
 */
function stripSymbols(data: any): any;

/**
 * Wait utility for async testing
 * @param milliseconds - Time to wait in milliseconds
 * @returns Promise that resolves after specified time
 */
function wait(milliseconds?: number): Promise<void>;

Usage Examples:

import { createClient, stripSymbols, wait } from "react-apollo";

describe("Testing utilities", () => {
  it("creates test client", () => {
    const client = createClient({
      cache: new InMemoryCache(),
      resolvers: {
        Query: {
          user: () => ({ id: "1", name: "Test User" })
        }
      }
    });

    expect(client).toBeInstanceOf(ApolloClient);
  });

  it("strips Apollo symbols from data", () => {
    const dataWithSymbols = {
      id: "1",
      name: "Test",
      __typename: "User",
      [Symbol.for("apollo.cacheKey")]: "User:1"
    };

    const cleanData = stripSymbols(dataWithSymbols);
    
    expect(cleanData).toEqual({
      id: "1",
      name: "Test",
      __typename: "User"
    });
  });

  it("waits for async operations", async () => {
    const start = Date.now();
    await wait(100);
    const end = Date.now();
    
    expect(end - start).toBeGreaterThanOrEqual(100);
  });
});

Testing Patterns

Testing with React Testing Library

import React from "react";
import { render, fireEvent, waitFor } from "@testing-library/react";
import { MockedProvider } from "react-apollo";
import { CreateUserForm } from "./CreateUserForm";

describe("CreateUserForm", () => {
  it("submits user creation", async () => {
    const CREATE_USER = gql`
      mutation CreateUser($input: UserInput!) {
        createUser(input: $input) {
          id
          name
          email
        }
      }
    `;

    const mocks = [
      {
        request: {
          query: CREATE_USER,
          variables: {
            input: { name: "John Doe", email: "john@example.com" }
          }
        },
        result: {
          data: {
            createUser: {
              id: "1",
              name: "John Doe",
              email: "john@example.com"
            }
          }
        }
      }
    ];

    const { getByLabelText, getByText } = render(
      <MockedProvider mocks={mocks}>
        <CreateUserForm />
      </MockedProvider>
    );

    fireEvent.change(getByLabelText("Name"), {
      target: { value: "John Doe" }
    });
    fireEvent.change(getByLabelText("Email"), {
      target: { value: "john@example.com" }
    });
    fireEvent.click(getByText("Create User"));

    await waitFor(() => {
      expect(getByText("User created successfully")).toBeInTheDocument();
    });
  });
});

Testing Error Scenarios

describe("Error handling", () => {
  it("displays network errors", async () => {
    const mocks = [
      {
        request: {
          query: GET_USER_QUERY,
          variables: { id: "1" }
        },
        error: new Error("Network error")
      }
    ];

    const { getByText } = render(
      <MockedProvider mocks={mocks}>
        <UserProfile userId="1" />
      </MockedProvider>
    );

    await waitFor(() => {
      expect(getByText("Network error")).toBeInTheDocument();
    });
  });

  it("displays GraphQL errors", async () => {
    const mocks = [
      {
        request: {
          query: GET_USER_QUERY,
          variables: { id: "1" }
        },
        result: {
          errors: [{ message: "User not found" }]
        }
      }
    ];

    const { getByText } = render(
      <MockedProvider mocks={mocks}>
        <UserProfile userId="1" />
      </MockedProvider>
    );

    await waitFor(() => {
      expect(getByText("User not found")).toBeInTheDocument();
    });
  });
});