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.
How to use?
Add it to your plugins:
import { defineConfig, useMock } from '@graphql-hive/gateway'
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:
import { defineConfig, useMock } from '@graphql-hive/gateway'
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;
import { defineConfig, useMock } from '@graphql-hive/gateway'
import { user } from './user-mocks.js'
export const gatewayConfig = defineConfig({
plugins: pluginCtx => [
useMock({
mocks: [
{
apply: 'User',
custom: user
}
]
})
]
})
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:
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
}
import { defineConfig, useMock } from '@graphql-hive/gateway'
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:
import { MockStore } from '@graphql-hive/gateway'
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
}
import { defineConfig, useMock } from '@graphql-hive/gateway'
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
}
import { defineConfig, useMock } from '@graphql-hive/gateway'
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
}
}
]
})
]
})