Quick start
This guide gets you from an empty test file to a passing test that seeds data, runs code against the commercetools SDK, and asserts on the result. It uses Vitest, but the same pattern works in Jest.
The recommended pattern
Section titled “The recommended pattern”Since version 2, the mock is built on msw. The recommended
approach is to manage the msw server yourself and register the mock’s
handlers on it with registerHandlers. That way the same server can also mock
your other APIs.
-
Create the mock and an msw server.
setup.test.ts import { CommercetoolsMock } from '@labdigital/commercetools-mock'import { setupServer } from 'msw/node'const ctMock = new CommercetoolsMock({defaultProjectKey: 'my-project',})const mswServer = setupServer() -
Wire up the lifecycle hooks.
setup.test.ts beforeAll(() => {mswServer.listen({ onUnhandledRequest: 'error' })})beforeEach(() => {ctMock.registerHandlers(mswServer)})afterEach(async () => {mswServer.resetHandlers()await ctMock.clear()})afterAll(() => {mswServer.close()})registerHandlersadds the mock’s request handlers to your server.mswServer.resetHandlers()removes them after each test.ctMock.clear()wipes the in-memory data so tests stay isolated.
-
Point your commercetools client at an intercepted host.
By default the mock intercepts the wildcard hosts
https://api.*.commercetools.comandhttps://auth.*.commercetools.com, so a client already configured for a real commercetools region is intercepted automatically:import { ClientBuilder } from '@commercetools/sdk-client-v2'import { createApiBuilderFromCtpClient } from '@commercetools/platform-sdk'const host = 'https://api.europe-west1.gcp.commercetools.com'const authHost = 'https://auth.europe-west1.gcp.commercetools.com'const client = new ClientBuilder().withClientCredentialsFlow({host: authHost,projectKey: 'my-project',credentials: { clientId: 'foo', clientSecret: 'bar' },}).withHttpMiddleware({ host }).build()export const apiRoot = createApiBuilderFromCtpClient(client).withProjectKey({ projectKey: 'my-project' })Prefer an explicit host? Set
apiHost/authHoston the mock and use the same value in your client. See Configuration options. -
Create data, run, assert.
Create the data your code needs through the commercetools API — the same calls your production code makes — then run the code under test and assert.
order.test.ts test('creates an order for the customer', async () => {// Create data through the APIawait apiRoot.customers().post({ body: { email: 'jane@example.com', password: 's3cret' } }).execute()// Run the code under test — it uses the SDK, which hits the mockconst order = await placeOrderForCustomer('jane@example.com')// Assertexpect(order.orderState).toBe('Open')})
Full example
Section titled “Full example”import { CommercetoolsMock } from '@labdigital/commercetools-mock'import { setupServer } from 'msw/node'import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test } from 'vitest'import { apiRoot } from './ct-client'
const ctMock = new CommercetoolsMock({ defaultProjectKey: 'my-project',})
describe('custom types', () => { const mswServer = setupServer()
beforeAll(() => mswServer.listen({ onUnhandledRequest: 'error' })) beforeEach(() => ctMock.registerHandlers(mswServer)) afterEach(async () => { mswServer.resetHandlers() await ctMock.clear() }) afterAll(() => mswServer.close())
test('creates a custom type', async () => { // Create through the API await apiRoot .types() .post({ body: { key: 'my-custom-type', name: { en: 'My type' }, resourceTypeIds: ['customer'], fieldDefinitions: [], }, }) .execute()
// Read it back through the API const type = await apiRoot .types() .withKey({ key: 'my-custom-type' }) .get() .execute()
expect(type.body.key).toBe('my-custom-type') })})Alternative: build the server from getHandlers()
Section titled “Alternative: build the server from getHandlers()”If you’d rather construct the msw server directly — for example to register
handlers for other APIs in the same call — use getHandlers():
import { setupServer } from 'msw/node'
const mswServer = setupServer(...ctMock.getHandlers())See msw integration for the difference
between registerHandlers and getHandlers.
Next steps
Section titled “Next steps”- How it works — the moving parts behind the mock.
- Seeding data — creating test data through the API, and fixtures.
- Configuration options — tune the mock to your needs.