Testing

If you are testing a library or a project that uses the SDK underneath, you probably don't want to make actual HTTP requests (unless you are doing integration tests).

There are several approaches to mock the requests, the easiest one we recommend to use is the nock library. This library allows to deeply customize how you want to mock the actual node http.request and it's very declarative, making it easy to use. Let's see an example:

// We'll mock a request to fetch some products
nock('https://api.commercetools.com')
  .defaultReplyHeaders({ 'Content-Type': 'application/json' })
  .get('/my-project/products')
  .reply(200, {
    total: 2,
    count: 2,
    results: [{ id: '1' }, { id: '2' }],
  })

// or mock a request to create a channel
nock('https://api.commercetools.com')
  .defaultReplyHeaders({ 'Content-Type': 'application/json' })
  .filteringRequestBody(() => '*')
  .post('/my-project/channels', '*')
  .reply(201, { id: '1' })

  // we could also do assertions on the body payload
  .filteringRequestBody((body) => {
    expect(body).toBe(JSON.stringify({ foo: 'bar' }))
    return '*'
  })

// Note that by default the defined mocks (or interceptors) are used only once
// https://github.com/node-nock/nock#read-this---about-interceptors
// To re-use the same interceptor for multiple requests simply call `persist()`
// https://github.com/node-nock/nock#persist

Mock middlewares

Another approach would be to provide a http-mock middleware that replaces the e.g. http middleware. It's a bit more work in terms of configuring the middleware for mocking different requests but it might be simpler for mocking requests in general and not caring about the response.

import { getErrorByCode } from '@commercetools/sdk-middleware-http'
const BadRequest = getErrorByCode(400)
const httpMockSuccessMiddleware = (next) => (request, response) => {
  next(request, { ...response, body: { foo: 'bar' } })
}
const httpMockFailureMiddleware = (next) => (request, response) => {
  next(request, { ...response, error: new BadRequest('Invalid field') })
}
const client = createClient({
  middlewares: [
    authMiddleware,
    httpMockSuccessMiddleware,
    // httpMockFailureMiddleware,
  ],
})

Mock modules

Furthermore, if you're using jest for testing, you might decide to define manual mocks for the SDK modules. You might think of using this if you just want to mock the SDK modules altogether.

// Note: once this PR is released (https://github.com/facebook/jest/pull/2483),
// setting up the mock can be done in
//   __mocks__/@commercetools/sdk-client.js
jest.mock('@commercetools/sdk-client', () => () => ({
  execute: jest.fn(() => Promise.resolve('Hello')),
}))

const createClient = require('@commercetools/sdk-client')

const client = createClient()

function testImplementation(request, cb) {
  client
    .execute(request)
    .then((result) => cb(null, result))
    .catch((error) => cb(error))
}

describe('SDK client', () => {
  it('use mocked version', () =>
    new Promise((resolve, reject) => {
      testImplementation({ uri: '/foo/bar' }, (error, data) => {
        if (error) {
          reject(error)
          return
        }
        expect(client.execute).toHaveBeenLastCalledWith({ uri: '/foo/bar' })
        expect(data).toBe('Hello')
        resolve()
      })
    }))
})

results matching ""

    No results matching ""