TypeScript
msw

TypeScript Msw

Package nameWeekly DownloadsVersionLicenseUpdated
@graphql-codegen/typescript-mswDownloadsVersionLicenseFeb 2nd, 2024

Installation

npm i -D @graphql-codegen/typescript-msw
⚠️

Usage Requirements In order to use this GraphQL Codegen plugin, please make sure that you have GraphQL operations (query / mutation / subscription and fragment) set as documents: … in your codegen.yml.

Without loading your GraphQL operations (query, mutation, subscription and fragment), you won’t see any change in the generated output.

This plugin generates msw (https://github.com/mswjs/msw) mock handlers with TypeScript typings.

Config API Reference

link

type: object

GraphQL endpoint to use when working with multiple backends.

Usage Examples

codegen.ts
 import type { CodegenConfig } from '@graphql-codegen/cli';
 
 const config: CodegenConfig = {
   // ...
   generates: {
     'path/to/file.ts': {
       // plugins...
       config: {
         link: {
           name: 'stripe',
           endpoint: 'https://api.stripe.com/graphql'
         }
       },
     },
   },
 };
 export default config;

MSW is a powerful tool for mocking HTTP requests in your tests and development environment. This plugin generates typed mock function wrappers for your GraphQL operations.

The generated functions are named with the pattern: mock<OperationName><OperationType>[LinkName]. As an example, a query with the name getUser would generate a mock function mockGetUserQuery. If you have links configured for multiple endpoints, the link name will be appended to the end. A link configured for the Stripe API, for example, would generate a mock name mockAdminMutationStripe. See below for more examples.

Configuration

To use this plugin, you need the typescript plugin and typescript-operations in your configuration.

If you are using the client you can simply add the typescript-msw plugin to your configuration:

codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli'
 
const config: CodegenConfig = {
  schema: 'schema.graphql',
  documents: ['src/**/*.tsx', 'src/**/*.ts', '!src/gql/**'],
  generates: {
    './src/gql/graphql.ts': {
      preset: 'client',
      plugins: ['typescript-msw']
    }
  }
}
export default config

Usage

The examples below assume the following GraphQL schema with a getUser query and a setEmail mutation.

schema.graphql
query GetUser($id: ID!) {
  GetUser(id: $id) {
    name
    email
    id
  }
}
 
mutation SetUsername($id: ID!, $name: String!) {
  SetUsername(id: $id, name: $name) {
    id
    name
  }
}

Mocking a query response

mocks.ts
import { mockGetUserQuery } from './generated'
import { HttpResponse } from 'msw'
 
const mockSuccess = mockGetUserQuery(({ variables }) => {
  const { id } = variables
 
  return HttpResponse.json({
    data: {
      getUser: { name: 'John Doe', id }
    }
  })
})
 
export mockUserQuerySuccess;

Mocking an error response

mocks.ts
import { mockGetUserQuery } from './generated'
import { HttpResponse } from 'msw'
 
const mockUserQueryError = mockGetUserQuery(({ variables }) => {
  return HttpResponse.json({
    errors: [
      {
        message: 'User not found'
      }
    ]
  })
})
 
export mockUserQueryError;

Accessing other resolver argument properties

The resolver function receives an object with a number of properties. The most up to date documentation is going to be in the msw docs site.

mockGetUserQuery({ query, variables, operationName, request }) => {})

Migrating from MSW 1.x to 2.x

MSW 2.x introduced a number of breaking changes. The types from msw are not compatible between the two versions so to upgrade, you will have to make some changes.

Updating the resolver function

You will need to update callback signatures to use the new resolver argument. In addition, the returned result must be a Response object.

msw-v1.ts
mockGetUserQuery((req, res, ctx) => {
  const { id } = req.variables
 
  return res(
    ctx.data({
      getUser: { name: 'John Doe', id }
    })
  )
})

After:

msw-v2.ts
import { HttpResponse } from 'msw'
mockGetUserQuery(({ variables }) => {
  const { id } = variables
 
  return HttpResponse.json({
    data: {
      getUser: { name: 'John Doe', id }
    }
  })
})

Replacing the res.once method

In addition to the changes above, since the res object does not get passed to the resolver, you will need to adjust. To achieve the same behavior, you can pass a second “options” parameter to the mock function.

msw-v1.ts
mockGetUserQuery((req, res, ctx) => {
  const { id } = req.variables
 
  return res.once(
    ctx.data({
      getUser: { name: 'John Doe', id }
    })
  )
})
msw-v2.ts
import { HttpResponse } from 'msw'
 
mockGetUserQuery(
  ({ variables }) => {
    const { id } = variables
 
    return HttpResponse.json({
      data: {
        getUser: { name: 'John Doe', id }
      }
    })
  },
  { once: true }
)