Mocking your GraphQL API
This page is currently under construction and expected to change. Please feel free to reach out to us directly in case you are having any troubles.
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?
npm install @graphql-mesh/plugin-mock
Then, add it to your plugins:
import useMock from '@graphql-mesh/plugin-mock'
import { defineConfig } from '@graphql-mesh/serve-cli'
export const serveConfig = 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 } from '@graphql-mesh/serve-cli'
import { fullName } from './user-mocks.js'
export const serveConfig = 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 } from '@graphql-mesh/serve-cli'
import { user } from './user-mocks.js'
export const serveConfig = 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
Mesh 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 useMock from '@graphql-mesh/plugin-mock'
import { defineConfig } from '@graphql-mesh/serve-cli'
export const serveConfig = 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
GraphQL Mesh 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-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
}
import { defineConfig } from '@graphql-mesh/serve-cli'
import { store } from './init-store.js'
export const serveConfig = 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 } from '@graphql-mesh/serve-cli'
import { store } from './init-store.js'
export const serveConfig = 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
}
}
]
})
]
})