---
searchable: false
---

import { Callout } from '@theguild/components'

# 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:

```ts filename="gateway.config.ts"
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](https://fakerjs.dev) 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:

```ts filename="gateway.config.ts"
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;

```ts filename="gateway.config.ts"
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
        }
      ]
    })
  ]
})
```

```ts filename="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:

```ts filename="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:

```graphql
type Query {
  users: [User]
}
type User {
  id: ID
  fullName: String
}
```

```ts filename="gateway.config.ts"
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 } }{:graphql}` query will return 3 of `User` item;

```json
{
  "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`;

<Callout>[Learn more about GraphQL Tools Mocking](https://graphql-tools.com/docs/mocking)</Callout>

### Initialize store

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

```ts filename="init-store.ts"
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:

```graphql
type Query {
  user(id: ID): User
}
```

```ts filename="gateway.config.ts"
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

```graphql
type User {
  id: ID
  name: String
}
type Query {
  me: User
}
type Mutation {
  changeMyName(newName: String): User
  updateUser(id: ID, name: String): User
}
```

```ts filename="gateway.config.ts"
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
          }
        }
      ]
    })
  ]
})
```
