The Guild LogoThe Guild Monogram

Search docs

Search icon

Products by The Guild

Products

Hive logoHive blurred logo

Hive

Schema Registry for your GraphQL Workflows

Skip to main content

Mock Transform

The mock transform allow you to apply mocking for development usage.

To get started with this transform, install it from npm:

yarn add @graphql-mesh/transform-mock

How to use?#

Add the following configuration to your Mesh config file:

transforms:
- mock:
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 mock a specific field of a type;

transforms:
- mock:
mocks:
- apply: User.fullName
custom: ./user-mocks#fullName

Custom mock functions for types#

You can mock types with custom mock functions like below;

transforms:
- mock:
mocks:
- apply: DateTime
custom: graphql-scalars#DateTimeMock
# This will import `DateTimeMock` from `graphql-scalars` for example. Local paths are also supported

in user-mocks.js file;

module.exports = {
fullName: () => 'My Static Name'
};

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, for example in an array. Here's an example on how this could be achieved:

in user-mocks.js file;

function* generateNames() {
while (true) {
yield "John Doe";
yield "John Snow";
}
}
const fullNames = generateNames();
export const fullName = () => fullNames.next().value;

and in case you are using typescript in user-mocks.ts file:

import { User } from './types/mesh';
function* generateNames(): Generator<string> {
while (true) {
yield "John Doe";
yield "John Snow";
}
}
const fullNames = generateNames();
export const fullName: () => User['fullName'] = () => fullNames.next().value;

Mocking the lists#

By default, Mesh generates two mocked items if the return type is a list. But this can be configured;

Let's say, you have a schema like below;

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

Then a configuration like below;

transforms:
- mock:
mocks:
- apply: User.fullName
faker: '{{name.fullName}}'
- apply: Query.users
length: 3

Now { 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's 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:

type User {
id: ID
name: String
}
type Query {
users: User
}

Initially populating the list of users can be done by utilizing the initializeStore property. The store initialization will happen before the store is attached to the schema.

In this case there is no need to provide special array mocking definition, like length. It will automatically be taken based on the mock data.

transforms:
- mock:
initializeStore: ./myMock#initializeStore

In the ./myMock.js:

const users = [{id: 'uuid', name: 'John Snow'}]
export default {
initializeStore: (store) => {
// 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
}
transforms:
- mock:
initializeStore: absolute-path-to-file/myMock#initializeStore
mocks:
- apply: Query.user
store:
type: User
key: "{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
}
transforms:
- mock:
mocks:
- apply: Mutation.changeMyName
custom: ./myMocks#changeMyName
- apply: Mutation.addUser
updateStore:
type: User
key: "{random}"
fieldName: name
value: "{args.name}"
# return created user
store:
type: User
key: "{random}"
- apply: Mutation.updateUser
custom: ./mocks#updateUser
# or you can do the following
updateStore:
type: User
key: "{args.id}"
fieldName: name
value: "{args.name}"
# return updated user
store:
type: User
key: "{args.id}"

In the code:

module.exports = {
changeMyName: (_, { newName }, { mockStore }) => {
mockStore.set('Query', 'ROOT', 'me', { name: newName });
return mockStore.get('Query', 'ROOT', 'me');
},
updateUser: (_, { id, name }, { mockStore }) => {
mockStore.set('User', id, { name });
return mockStore.get('User', id);
}
}

Learn more about GraphQL Tools Mocking; https://www.graphql-tools.com/docs/mocking

Codesandbox Example#

You can check out our example that uses JSON Schema handler with mock data.

Config API Reference#

  • if (type: Boolean) - If this expression is truthy, mocking would be enabled You can use environment variables expression, for example: ${MOCKING_ENABLED}
  • preserveResolvers (type: Boolean) - Do not mock any other resolvers other than defined in mocks. For example, you can enable this if you don't want to mock entire schema but partially.
  • mocks (type: Array of Object) - Mock configurations:
    • apply (type: String, required) - Resolver path Example: User.firstName
    • if (type: Boolean) - If this expression is truthy, mocking would be enabled You can use environment variables expression, for example: ${MOCKING_ENABLED}
    • faker (type: String) - Faker.js expression or function Read more (https://github.com/marak/Faker.js/#fakerfake) Example; faker: name.firstName faker: "{{ name.firstName }} {{ name.lastName }}"
    • custom (type: String) - Custom mocking It can be a module or json file. Both "moduleName#exportName" or only "moduleName" would work
    • length (type: Int) - Length of the mock list For the list types [ObjectType], how many ObjectType you want to return? default: 2
    • store (type: Object) - Get the data from the mock store:
      • type (type: String)
      • key (type: ID)
      • fieldName (type: String)
    • updateStore (type: Array of Object) - Update the data on the mock store:
      • type (type: String)
      • key (type: ID)
      • fieldName (type: String)
      • value (type: String)
  • initializeStore (type: Any) - The path to the code runs before the store is attached to the schema