Skip to Content

Mocking your GraphQL API

Mocking your GraphQL API is a common practice when developing and testing your application. It allows you to simulate the behavior of your API without making real network requests.

Installing

Start by installing the @graphql-mesh/plugin-mock package:

npm i @graphql-mesh/plugin-mock

How to use?

Add it to your plugins:

gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway' import { useMock } from '@graphql-mesh/plugin-mock' export const gatewayConfig = defineConfig({ plugins: [ useMock({ mocks: [ { apply: 'User.firstName', faker: '{{name.firstName}}' } ] }) ] })

The example above will replace the resolver of User.firstName with a mock that uses faker.js to generate a random name.

Custom mock functions for fields

You can also provide a custom function to generate the mock value for a field:

gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway' import { useMock } from '@graphql-mesh/plugin-mock' import { fullName } from './user-mocks.js' export const gatewayConfig = defineConfig({ plugins: pluginCtx => [ useMock({ mocks: [ { apply: 'User.fullName', custom: fullName } ] }) ] })

Custom mock functions for types

You can mock types with custom mock functions like below;

gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway' import { useMock } from '@graphql-mesh/plugin-mock' import { user } from './user-mocks.js' export const gatewayConfig = defineConfig({ plugins: pluginCtx => [ useMock({ mocks: [ { apply: 'User', custom: user } ] }) ] })
user-mocks.ts
export const mockFullName = () => { return `John Doe` }

When defined manually, properties can return values either directly or through a method. This is useful when defining static mocks because a mock property will be called as many times as there are items in an array. Here’s an example on how this could be achieved:

user-mocks.ts
function* generateNames() { while (true) { yield 'John Doe' yield 'John Snow' } } const fullNames = generateNames() export const fullName = () => fullNames.next().value

Mocking the lists

Hive Gateway generates two mocked items by default if the return type is a list. But this can be configured, as shown below:

type Query { users: [User] } type User { id: ID fullName: String }
gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway' import { useMock } from '@graphql-mesh/plugin-mock' export const gatewayConfig = defineConfig({ plugins: pluginCtx => [ useMock({ mocks: [ { apply: 'User.fullName', faker: '{{name.fullName}}' }, { apply: 'Query.users', length: 3 } ] }) ] })

Now query { users { id fullName } } query will return 3 of User item;

{ "users": [ { "id": "SOME_RANDOM_ID", "fullName": "John Doe" }, { "id": "SOME_RANDOM_ID", "fullName": "Jane Doe" }, { "id": "SOME_RANDOM_ID", "fullName": "The Other Doe" } ] }

Stateful mocking

Hive Gateway supports GraphQL Tools’ Stateful Mocking feature. So you can have stateful mocking by using the store provided in the context context.mockStore;

Initialize store

When having a schema that returns a list, in this case, a list of users:

init-store.ts
import { MockStore } from '@graphql-mesh/plugin-mock' export const store = new MockStore() const users = [{ id: 'uuid', name: 'John Snow' }] // Set individual users' data in the store so that they can be queried as individuals later on users.forEach(user => { store.set('User', user.id, user) }) // Populate the `users` query on the root with data store.set('Query', 'ROOT', 'users', users)

Get from the store

You can implement the mock query field *ById declaratively like below:

type Query { user(id: ID): User }
gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway' import { useMock } from '@graphql-mesh/plugin-mock' import { store } from './init-store.js' export const gatewayConfig = defineConfig({ plugins: pluginCtx => [ useMock({ store, mocks: [ { apply: 'Query.user', custom: (_, args) => store.get('User', args.id) } ] }) ] })

Mutate data in the store

type User { id: ID name: String } type Query { me: User } type Mutation { changeMyName(newName: String): User updateUser(id: ID, name: String): User }
gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway' import { useMock } from '@graphql-mesh/plugin-mock' import { store } from './init-store.js' export const gatewayConfig = defineConfig({ plugins: pluginCtx => [ useMock({ store, mocks: [ { apply: 'Query.me', custom: (_, args, context) => store.get('User', 'uuid') }, { apply: 'Mutation.changeMyName', custom: (_, args, context) => { const user = store.get('User', 'uuid') user.name = args.newName store.set('User', 'uuid', user) return user } }, { apply: 'Mutation.updateUser', custom: (_, args, context) => { const user = store.get('User', args.id) user.name = args.name store.set('User', args.id, user) return user } } ] }) ] })
Last updated on