Skip to content
 
 

Repository files navigation

@blurb/msw-trpc



This is a fork. msw-trpc by Malo Guertin, forked at 2.0.1 and published to GitHub Packages as @blurb/msw-trpc for use inside the org. It adds handler fallthrough on top of upstream. See Releasing to cut a new version.

tPRC support for MSW

  • Create MSW handlers from your tRPC router.
  • Get your tRPC typing into your MSW handlers.
  • Augments MSW with utils for tRPC.
  • Use it like you would use the tRPC client.
  • Merged routers supported !
  • Use msw v2

Motivation

As someone who loves MSW and was already using it I wanted to keep using it instead of mocking tRPC. While it is possible to simply write the Rest handlers it felt like it would be great not to lose the full power of tRPC types in the tests.

Usage

1. Point the @blurb scope at GitHub Packages.

GitHub Packages requires authentication even for public packages, so the consuming repo needs an .npmrc:

@blurb:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}

NODE_AUTH_TOKEN can be a personal access token with read:packages, or — in GitHub Actions — the built-in secrets.GITHUB_TOKEN, since this package is public.

2. Install @blurb/msw-trpc.

npm i @blurb/msw-trpc --save-dev

3. build your trpcMsw with createTRPCMsw.

import { createTRPCMsw } from '@blurb/msw-trpc'
import type { AppRouter } from 'path/to/your/router'

export const trpcMsw = createTRPCMsw<AppRouter>() /* 👈 */

4. Start using it.

const server = setupServer(
  trpcMsw.userById.query(() => ({ id: '1', name: 'Uncle bob' })),
  trpcMsw.createUser.mutation((name) => ({ id: '2', name }))
)

You can find examples of how to use it in the test-react package or in the test-node package.

How it works

createTRPCMsw returns a Proxy that infers types from your AppRouter

// all queries will expose a query function that accepts a MSW handler
trpcMsw.myQuery.query(() => {})

// all mutations will expose a mutation function that accepts a MSW handler
trpcMsw.myMutation.mutation(() => {})

Fallthrough

Return the fallthrough sentinel from a mock to decline the request, so MSW keeps looking for the next matching handler. This is MSW's handler fallthrough, and it lets you mock a procedure conditionally on its input:

import { createTRPCMsw, fallthrough } from '@blurb/msw-trpc'

server.use(
  trpcMsw.userById.query(({ input }) => (input === '1' ? { id: '1', name: 'Uncle bob' } : fallthrough)),
  trpcMsw.userById.query(() => ({ id: '99', name: 'Anyone else' }))
)

Handlers are tried in the order given within a single use() call, so the declining handler goes first. The next handler can be another msw-trpc handler or a plain http.* one.

Returning undefined is not a fallthrough — it responds with an empty tRPC result, which is the correct response for a procedure that returns nothing. Throwing a TRPCError is not a fallthrough either: mocking an error handles the request.

One MSW behaviour to be aware of: if every matching handler declines, the request goes to the real network. onUnhandledRequest: 'error' does not catch it, because a declining handler still counts as a match.

Config

You need to pass a httpLink to the createTRPCMsw function like you would do with the tRPC client.

You can pass an optional transformer like superjson to the createTRPCMsw function.

interface TRPCMswConfig {
  links: Link[]
  transformer?: TRPCCombinedDataTransformer
}

Requirements

Peer dependencies:

  • tRPC server v11 (@trpc/server@next) must be installed.
  • msw (msw) must be installed.

Please note:

  • Batch is not yet supported

Releasing

@blurb/msw-trpc is published to GitHub Packages by .github/workflows/npm-publish.yml, which runs on a published GitHub Release and authenticates with the workflow's built-in GITHUB_TOKEN.

  1. Bump version in packages/msw-trpc/package.json and merge that to main.

  2. Cut a release whose tag matches that version — the workflow fails fast if they disagree:

    gh release create v2.1.0 --title v2.1.0 --notes 'Add handler fallthrough support'
  3. Watch it publish with gh run watch, then confirm at the package page.

Versions follow upstream's numbering: the fork's base is upstream 2.0.1, and fork-only changes bump from there.

About

tPRC support for MSW

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages