Test utilities including mock implementations and testing helpers for validating link behavior.
Mock implementation of ApolloLink for testing purposes that allows custom request handling.
/**
* Mock implementation of ApolloLink for testing
*/
class MockLink extends ApolloLink {
/**
* Creates a new MockLink with optional request handler
* @param handleRequest - Optional request handler function (defaults to returning null)
*/
constructor(handleRequest?: RequestHandler);
/**
* Processes GraphQL operation (should be overridden in constructor)
* @param operation - GraphQL operation
* @param forward - Forward function (for non-terminating mocks)
* @returns Observable or null
*/
request(operation: Operation, forward?: NextLink): Observable<FetchResult> | null;
}Usage Examples:
import { MockLink, Observable } from "apollo-link";
// Mock link that returns predefined data
const mockLink = new MockLink((operation) => {
return new Observable(observer => {
if (operation.operationName === "GetUser") {
observer.next({
data: { user: { id: "123", name: "John Doe" } }
});
observer.complete();
} else {
observer.error(new Error("Unknown operation"));
}
});
});
// Mock link that simulates errors
const errorMockLink = new MockLink(() => {
return new Observable(observer => {
observer.error(new Error("Network error"));
});
});
// Mock link for testing forwarding behavior
const forwardingMockLink = new MockLink((operation, forward) => {
// Modify operation and forward
operation.setContext({ timestamp: Date.now() });
return forward ? forward(operation) : Observable.of();
});Link that modifies the operation context using a provided function, useful for testing context manipulation.
/**
* Link that modifies operation context for testing
*/
class SetContextLink extends ApolloLink {
/**
* Creates a link that modifies operation context
* @param setContext - Function to modify context (defaults to identity function)
*/
constructor(setContext?: (context: Record<string, any>) => Record<string, any>);
/**
* Modifies operation context and forwards to next link
* @param operation - GraphQL operation
* @param forward - Forward function to next link
* @returns Observable from forwarded operation
*/
request(operation: Operation, forward: NextLink): Observable<FetchResult>;
}Usage Examples:
import { SetContextLink, from } from "apollo-link";
// Add authentication headers
const authContextLink = new SetContextLink((context) => ({
...context,
headers: {
...context.headers,
Authorization: "Bearer test-token"
}
}));
// Add request timestamp
const timestampLink = new SetContextLink((context) => ({
...context,
requestTime: Date.now()
}));
// Chain with other links
const link = from([authContextLink, timestampLink, httpLink]);Executes a link with a GraphQL operation and validates the results against expected outcomes.
/**
* Executes a link and validates results against expected outcomes
* @param params - Test configuration object
*/
function testLinkResults(params: TestResultType): void;
interface TestResultType {
/** Link to test */
link: ApolloLink;
/** Expected results array (optional) */
results?: any[];
/** GraphQL query string or AST (optional, uses default if not provided) */
query?: string;
/** Callback to invoke when test completes (optional) */
done?: () => void;
/** Context to pass with operation (optional) */
context?: any;
/** Variables to pass with operation (optional) */
variables?: any;
}Usage Examples:
import { testLinkResults, MockLink } from "apollo-link";
import gql from "graphql-tag";
// Test successful response
const successLink = new MockLink(() =>
Observable.of({ data: { user: { id: "123" } } })
);
testLinkResults({
link: successLink,
results: [{ user: { id: "123" } }],
query: gql`query { user { id } }`,
done: () => console.log("Test completed")
});
// Test error handling
const errorLink = new MockLink(() =>
Observable.throw(new Error("Test error"))
);
testLinkResults({
link: errorLink,
results: [new Error("Test error")], // Errors go at the end of results array
done: () => console.log("Error test completed")
});
// Test with context and variables
testLinkResults({
link: contextAwareLink,
results: [{ data: { posts: [] } }],
context: { userId: "123" },
variables: { limit: 10 },
query: gql`query GetPosts($limit: Int!) { posts { id title } }`
});Helper function for checking function call results in tests, typically used internally by testLinkResults.
/**
* Helper for checking function call results in tests
* @param calls - Array of function calls (typically jest.fn().mock.calls)
* @param results - Expected results array
*/
function checkCalls<T>(calls: any[], results: Array<T>): void;Usage Example:
import { checkCalls } from "apollo-link";
// Typically used with Jest mocks
const mockFn = jest.fn();
// Simulate some calls
mockFn({ data: { user: "John" } });
mockFn({ data: { user: "Jane" } });
// Check that calls match expected results
checkCalls(mockFn.mock.calls, [
{ user: "John" },
{ user: "Jane" }
]);import { from, split, MockLink, testLinkResults } from "apollo-link";
describe("Link composition", () => {
it("should chain links correctly", () => {
const authLink = new MockLink((op, forward) => {
op.setContext({ auth: "token" });
return forward(op);
});
const httpLink = new MockLink((op) => {
const context = op.getContext();
expect(context.auth).toBe("token");
return Observable.of({ data: { success: true } });
});
const link = from([authLink, httpLink]);
testLinkResults({
link,
results: [{ success: true }],
done: () => console.log("Composition test passed")
});
});
});import { split, MockLink } from "apollo-link";
const httpLink = new MockLink(() =>
Observable.of({ data: { query: "http" } })
);
const wsLink = new MockLink(() =>
Observable.of({ data: { subscription: "ws" } })
);
const link = split(
({ query }) => query.definitions[0].operation === "subscription",
wsLink,
httpLink
);
// Test subscription routing
testLinkResults({
link,
query: gql`subscription { messageAdded { id } }`,
results: [{ subscription: "ws" }]
});
// Test query routing
testLinkResults({
link,
query: gql`query { users { id } }`,
results: [{ query: "http" }]
});import { MockLink, fromError } from "apollo-link";
const networkErrorLink = new MockLink(() =>
fromError(new Error("Network timeout"))
);
const graphqlErrorLink = new MockLink(() =>
Observable.of({
errors: [{ message: "User not found" }],
data: null
})
);
// Test network errors
testLinkResults({
link: networkErrorLink,
results: [new Error("Network timeout")]
});
// Test GraphQL errors
testLinkResults({
link: graphqlErrorLink,
results: [{
errors: [{ message: "User not found" }],
data: null
}]
});