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

Envelop Logo

Envelop

Get Started

Testing#

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 envrionment, so you don't need to deal with HTTP or anything else.

To get stated with the Envelop testkit, make sure to install it in your project (as a devDependency):

yarn add -D @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 { useMyPlugin } from './my-plugin'; import { createTestkit, assertSingleExecutionValue } from '@envelop/testing'; describe('My Plugin', () => { const mySchema = buildSchema(`type Query { foo: String }`); 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).toBeDefined(); }); });

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 { getEnveloped } from './my-app'; import { createTestkit, assertSingleExecutionValue } from '@envelop/testing'; describe('My GQL App', () => { const mySchema = buildSchema(`type Query { foo: String }`); 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).toBeDefined(); }); });

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 authenticate 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 schema const testkit = createTestkit(getEnveloped, mySchema); // Modify the envelop's plugins testkit.modifyPlugins(plugins => [...plugins, somePlugins]); // Execute the envelop using a simple query const result = await testkit.execute(`query testQuery { foo }`);

You can either add plugins, but also replace/remove plugins that are not needed during testing.

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 schema const testkit = createTestkit(getEnveloped, mySchema); // Replace the entire context factory phase testkit.mockPhase({ phase: 'contextFactory', fn: () => ({ currentUser: { id: 1, }, }), });

Note: Replacing whole phases might effect plugins execution, so use it carefully!

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 { getEnveloped } from './my-app'; import { createTestkit, assertSingleExecutionValue } from '@envelop/testing'; 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), }); }); });