Stateful storage system for consistent mock data across GraphQL queries. The MockStore provides reference tracking, data persistence, and advanced querying capabilities for complex testing scenarios where data consistency is crucial.
Core class providing stateful mock data storage with reference tracking and consistent query results.
/**
* Stateful store for managing mock data with consistent results across queries
*/
class MockStore implements IMockStore {
public schema: GraphQLSchema;
/**
* Create a new MockStore instance
* @param options - Configuration for the store
*/
constructor(options: {
schema: GraphQLSchema;
mocks?: IMocks;
typePolicies?: { [typeName: string]: TypePolicy };
});
/**
* Retrieve mock data from the store
*/
get<KeyT extends KeyTypeConstraints = string>(
typeName: string,
key?: KeyT,
defaultValue?: { [fieldName: string]: any }
): unknown | Ref<KeyT>;
get<KeyT extends KeyTypeConstraints = string, ReturnKeyT extends KeyTypeConstraints = string>(
typeName: string,
key: KeyT,
fieldNameOrFieldNames: string | string[],
fieldArgs?: string | { [argName: string]: any }
): unknown | Ref<ReturnKeyT>;
get<KeyT extends KeyTypeConstraints = string, ReturnKeyT extends KeyTypeConstraints = string>(
ref: Ref<KeyT>,
fieldNameOrFieldNames: string | string[],
fieldArgs?: string | { [argName: string]: any }
): unknown | Ref<ReturnKeyT>;
/**
* Store mock data in the store
*/
set<KeyT extends KeyTypeConstraints = string>(
typeName: string,
key: KeyT,
values: { [fieldName: string]: any }
): void;
set<KeyT extends KeyTypeConstraints = string>(
typeName: string,
key: KeyT,
fieldName: string,
value?: unknown
): void;
set<KeyT extends KeyTypeConstraints = string>(
ref: Ref<KeyT>,
fieldName: string,
value?: unknown
): void;
set<KeyT extends KeyTypeConstraints = string>(
ref: Ref<KeyT>,
values: { [fieldName: string]: any }
): void;
/**
* Check if data exists for the given type and key
*/
has<KeyT extends KeyTypeConstraints = string>(typeName: string, key: KeyT): boolean;
/**
* Clear all stored data
*/
reset(): void;
/**
* Filter entities by predicate function
* @param key - Type name to filter
* @param predicate - Filter function
* @returns Array of matching entities
*/
filter(key: string, predicate: (val: Entity) => boolean): Entity[];
/**
* Find entity by predicate function
* @param key - Type name to search
* @param predicate - Search function
* @returns First matching entity or undefined
*/
find(key: string, predicate: (val: Entity) => boolean): Entity | undefined;
}Usage Examples:
import { buildSchema } from "graphql";
import { MockStore, addMocksToSchema } from "@graphql-tools/mock";
const schema = buildSchema(`
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
author: User!
}
type Query {
user(id: ID!): User
users: [User!]!
}
`);
// Create a mock store
const store = new MockStore({
schema,
mocks: {
User: () => ({
id: () => `user_${Math.random().toString(36).substr(2, 9)}`,
name: () => ['Alice', 'Bob', 'Charlie'][Math.floor(Math.random() * 3)]
})
}
});
// Pre-populate the store with specific data
store.set('User', 'user_1', {
name: 'John Doe',
email: 'john@example.com'
});
// Retrieve data from store
const user = store.get('User', 'user_1');
const userName = store.get('User', 'user_1', 'name');
// Check if data exists
if (store.has('User', 'user_1')) {
console.log('User exists in store');
}
// Use store with schema
const mockedSchema = addMocksToSchema({
schema,
store
});Convenient factory function for creating MockStore instances.
/**
* Factory function to create IMockStore instances
* @param options - Configuration for the store
* @returns IMockStore instance
*/
function createMockStore(options: {
schema: GraphQLSchema;
mocks?: IMocks;
typePolicies?: { [typeName: string]: TypePolicy };
}): IMockStore;Usage Examples:
// Create store using factory function
const store = createMockStore({
schema,
mocks: {
User: () => ({
name: () => 'Generated User'
})
},
typePolicies: {
User: { keyFieldName: 'id' },
Post: { keyFieldName: 'id' }
}
});Interface defining the contract for mock store implementations.
/**
* Interface for mock store implementations
*/
interface IMockStore {
schema: GraphQLSchema;
get<KeyT extends KeyTypeConstraints = string, ReturnKeyT extends KeyTypeConstraints = string>(
args: GetArgs<KeyT>
): unknown | Ref<ReturnKeyT>;
get<KeyT extends KeyTypeConstraints = string, ReturnKeyT extends KeyTypeConstraints = string>(
typeName: string,
key: KeyT,
fieldNameOrFieldNames: string | string[],
fieldArgs?: string | { [argName: string]: any }
): unknown | Ref<ReturnKeyT>;
set<KeyT extends KeyTypeConstraints = string>(args: SetArgs<KeyT>): void;
set<KeyT extends KeyTypeConstraints = string>(
typeName: string,
key: KeyT,
fieldName: string,
value?: unknown
): void;
has<KeyT extends KeyTypeConstraints = string>(typeName: string, key: KeyT): boolean;
reset(): void;
}Type definitions for store operations and arguments.
/**
* Entity type for stored data
*/
type Entity = {
[key: string]: unknown;
};
/**
* Allowed key types for store operations
*/
type KeyTypeConstraints = string | number;
/**
* Arguments for get operations
*/
type GetArgs<KeyT extends KeyTypeConstraints = string> = {
typeName: string;
key?: KeyT;
fieldName?: string;
fieldArgs?: string | { [argName: string]: any };
defaultValue?: unknown | { [fieldName: string]: any };
};
/**
* Arguments for set operations
*/
type SetArgs<KeyT extends KeyTypeConstraints = string> = {
typeName: string;
key: KeyT;
fieldName?: string;
fieldArgs?: string | { [argName: string]: any };
value?: unknown | { [fieldName: string]: any };
noOverride?: boolean;
};The store uses a reference system to maintain relationships between entities.
/**
* Reference to a stored entity
*/
type Ref<KeyT extends KeyTypeConstraints = string> = {
$ref: {
key: KeyT;
typeName: string;
};
};Utility functions for working with references.
/**
* Type guard to check if a value is a reference
* @param maybeRef - Value to check
* @returns Type predicate for Ref
*/
function isRef<KeyT extends KeyTypeConstraints = string>(
maybeRef: unknown
): maybeRef is Ref<KeyT>;
/**
* Assert that a value is a reference, throwing if not
* @param maybeRef - Value to check
* @param message - Optional error message
*/
function assertIsRef<KeyT extends KeyTypeConstraints = string>(
maybeRef: unknown,
message?: string
): asserts maybeRef is Ref<KeyT>;
/**
* Create a reference object
* @param typeName - GraphQL type name
* @param key - Entity key
* @returns Reference object
*/
function makeRef<KeyT extends KeyTypeConstraints = string>(
typeName: string,
key: KeyT
): Ref<KeyT>;
/**
* Type guard to check if a value is a record object
* @param obj - Value to check
* @returns Type predicate for record
*/
function isRecord(obj: unknown): obj is { [key: string]: unknown };Usage Examples:
// Working with references
const userRef = makeRef('User', 'user_1');
// Check if value is a reference
if (isRef(someValue)) {
console.log(`Reference to ${someValue.$ref.typeName}:${someValue.$ref.key}`);
}
// Assert reference type
assertIsRef(userRef, 'Expected a user reference');
// Store relationships using references
store.set('Post', 'post_1', {
title: 'My Post',
author: userRef
});// Set up related entities
store.set('User', '1', {
name: 'Alice',
email: 'alice@example.com'
});
store.set('Post', '1', {
title: 'GraphQL Best Practices',
author: makeRef('User', '1')
});
// Query will resolve relationships automatically
const post = store.get('Post', '1');
const author = store.get(post.author); // Resolves to User:1// Filter users by predicate
const activeUsers = store.filter('User', (user) => user.active === true);
// Find specific user
const adminUser = store.find('User', (user) => user.role === 'admin');// Clear all data for testing isolation
store.reset();
// Store is now empty and ready for new test data