Envelop comes with a dedicated package for testing purposes. You can use it to test your plugin, or
your whole envelop, by replacing or mocking other plugins/phases.
The Envelop Testkit can also help you to test your envelop plugins in a headless environment, so you
don’t need to deal with HTTP or anything else.
To get started with the Envelop Testkit, make sure to install it in your project (as a
devDependency):
npm i -D @envelop/testing
yarn add --dev @envelop/testing
pnpm add -D @envelop/testing
bun add --dev @envelop/testing
To get started with your envelop testing, make sure first to setup your favorite test runner in
your project (we use Jest).
Testing a Plugin
To test a plugin in a real GraphQL environment, just create a Testkit Envelop:
import { assertSingleExecutionValue, createTestkit } from '@envelop/testing'import { makeExecutableSchema } from '@graphql-tools/schema'import { useMyPlugin } from './my-plugin'describe('My Plugin', () => { const mySchema = makeExecutableSchema({ typeDefs: `type Query { foo: String }`, resolvers: { Query: { foo: () => 'bar' } } }) it('Should run correctly with no errors', async () => { // Create a testkit for the plugin, using the plugin and a dummy schema const testkit = createTestkit([useMyPlugin], mySchema) // Execute the envelop using a simple query const result = await testkit.execute(`query testQuery { foo }`) // During tests, it's simpler to assume you are dealing with a non-stream responses assertSingleExecutionValue(result) // Assert that the result is correct expect(result.data?.foo).toBe('bar') })})
Testing Envelop Instance
You can also pass a complete instance of envelop (the getEnveloped function) to your Testkit,
and run the same testing flow for multiple plugins together:
import { assertSingleExecutionValue, createTestkit } from '@envelop/testing'import { makeExecutableSchema } from '@graphql-tools/schema'import { getEnveloped } from './my-app'describe('My GQL App', () => { const mySchema = makeExecutableSchema({ typeDefs: `type Query { foo: String }`, resolvers: { Query: { foo: () => 'bar' } } }) it('Should run correctly with no errors', async () => { // Create a testkit based on the envelop, with a dummy schema const testkit = createTestkit(getEnveloped, mySchema) // Execute the envelop using a simple query const result = await testkit.execute(`query testQuery { foo }`) // During tests, it's simpler to assume you are dealing with a non-stream responses assertSingleExecutionValue(result) // Assert that the result is correct expect(result.data?.foo).toBe('bar') })})
Additional Resources
Manipulating Envelops
If you are testing a complete envelop, you might want to manipulate the Envelop before executing
it (for example, to replace a context function that authenticates the user, or to create a scenario
needed for testing).
You can use modifyPlugins in order to modify the plugins that are part of your execution:
// Create a Testkit based on the Envelop, with a dummy schemaconst testkit = createTestkit(getEnveloped, mySchema)// Modify the Envelop's pluginstestkit.modifyPlugins(plugins => [...plugins, somePlugins])// Execute the Envelop using a simple queryconst result = await testkit.execute(`query testQuery { foo }`)
Mocking Phases
If you need to make sure that a specific phase of envelop will perform a specific result, you can
replace the entire phase with a custom one.
This is useful if you need to prepare with a specific scenario before running your Envelop, without
the need to deal with specific plugins.
Here’s an example for replacing the whole context-building phase:
// Create a testkit based on the envelop, with a dummy schemaconst testkit = createTestkit(getEnveloped, mySchema)// Replace the entire context factory phasetestkit.mockPhase({ phase: 'contextFactory', fn: () => ({ currentUser: { id: 1 } })})
Spying on Phases
If you are using Jest, you can use a pre-defined plugin that can help you spy on Envelop phases and
check the validity of your parameters.
import { assertSingleExecutionValue, createTestkit } from '@envelop/testing'import { getEnveloped } from './my-app'describe('My GQL App', () => { const mySchema = buildSchema(`type Query { foo: String }`) it('Should run correctly with no errors', async () => { const spy = createSpiedPlugin() const testkit = createTestkit(getEnveloped, mySchema) testkit.modifyPlugins(plugins => [...plugins, spy.plugin]) const result = await testkit.execute(`query testQuery { foo }`) assertSingleExecutionValue(result) // Assert and test expect(spy.spies.beforeContextBuilding).toHaveBeenCalledWith({ context: expect.objectContaining({ test: true }), extendContext: expect.any(Function) }) })})
This site uses cookies for analytics and improving your experience.