Testing Reference
Everything on this page is exported from openapi-backend/testing:
import { createTestClient, lambda, RoutingError, ResponseValidationError } from 'openapi-backend/testing';
import type { TestClient, TestRequest, TestResponse, SentRequest, TestAdapter } from 'openapi-backend/testing';
createTestClient(api, options?)
Creates a test client for an OpenAPIBackend instance.
import { createTestClient } from 'openapi-backend/testing';
import type { Operations } from './types/openapi';
const client = createTestClient<Operations>(api, { app });
The type parameter is optional. Pass the Operations type generated by
openapi typegen --backend to type operation methods.
The client initializes api on its first request, if it isn't initialized yet.
Options
| Option | Type | Description |
|---|---|---|
app | TestApp | Where to send requests. See Frameworks. |
transformResponse | function | Without app: turns the value api.handleRequest() returns into a response. See No framework. |
basePath | string | Path prepended to the paths of operations. Default: api.apiRoot |
headers | object | Headers for every request |
query | object | Query parameters for every request |
cookies | object | Cookies for every request |
security | object | Security handler stubs for every request |
example | boolean or string | Build every request from examples |
validateResponse | boolean | Check responses against the spec. Default: true |
Either app or transformResponse is required.
TestClient
client.operationId(request?)
Every operation in your API definition has a method named after its operationId.
Builds a request for the operation, sends it, and resolves to a TestResponse for any status code. Throws:
- an
Errorif the operation doesn't exist, or a path parameter is missing - a
RoutingErrorif the request is routed to another operation, or to none - a
ResponseValidationErrorif the response doesn't match the spec, unlessvalidateResponseisfalse
const res = await client.getPetById({ params: { id: 1 } });
Parameters:
request:TestRequest
Returns: Promise<TestResponse>
client.call(operationId, request?)
The same as calling the operation method. For table-driven tests, and operations whose operationId clashes with a
client method.
const res = await client.call('getPetById', { params: { id: 1 } });
client.request(request, options?)
Sends a raw request, without building it from an operation. If the router matches an operation, the response is still checked against the spec.
await client.request('GET /pets?limit=10');
await client.request('POST /pets', { body: { name: 'Garfield' } });
await client.request({ method: 'GET', path: '/pets', query: { limit: 10 } });
Parameters:
request: a string with the method, path and an optional query string, or an object withmethodandpathoptions:TestRequest, withoutparamsandexample
Returns: Promise<TestResponse>
client.with(defaults)
Returns a new client that adds defaults to every request. defaults takes the same options as
TestRequest, except params and body. The original client doesn't change.
const alice = client.with({ headers: { authorization: `Bearer ${token}` } });
client.api
The OpenAPIBackend instance the client was created for.
TestRequest
Options for a request. All are optional.
| Option | Type | Description |
|---|---|---|
params | object | Path parameters. Filled into the path template and URL-encoded. |
query | object | Query parameters. Serialized with the style and explode of each parameter in the spec. |
headers | object | Request headers. Arrays are sent as comma separated values. |
cookies | object | Cookies, sent in the Cookie header |
body | unknown | The request body. Objects are encoded as the operation's media type. Strings, Buffers, URLSearchParams and FormData are sent as they are. |
contentType | string | The media type to send the body as. Default: the operation's media type, preferring application/json |
example | boolean or string | true builds the request from the spec's examples, a string picks a named example. Other options are deep merged into it. |
security | object | Results to use instead of calling the security handlers, by security scheme name |
validateResponse | boolean | false skips checking the response against the spec |
Options passed to a request override defaults from createTestClient() and client.with(). headers, query,
cookies and security are merged key by key. Setting a key to undefined removes it.
TestResponse
| Property | Type | Description |
|---|---|---|
status | number | The HTTP status code |
headers | object | Response headers, with lowercase names. Several values for one header are joined with , . |
body | any | The body. JSON is parsed. Other text is a string, binary content is a Buffer, and an empty body is undefined. Typed from your spec with a typed client. |
operationId | string or undefined | The operation the request was routed to |
operation | Operation or undefined | The matched Operation object |
context | Context | The Context object openapi-backend built for the request. undefined if the request never reached api.handleRequest() in the same process. |
request | SentRequest | The request that was sent |
operation, context and request aren't enumerable.
SentRequest
The request the client sent. It's also a valid openapi-backend Request object.
| Property | Type | Description |
|---|---|---|
method | string | The HTTP method, in uppercase |
path | string | The path, without the query string |
url | string | The path, with the query string |
query | string | The query string, without the ? |
headers | object | The request headers, with lowercase names |
body | string, Buffer or undefined | The encoded body |
lambda(handler, options?)
Creates an adapter that sends requests to an AWS Lambda handler as API Gateway events. See Frameworks.
import { createTestClient, lambda } from 'openapi-backend/testing';
const app = lambda(handler, { event: 'v2' });
const client = createTestClient(api, { app });
| Option | Type | Description |
|---|---|---|
event | 'v1' or 'v2' | 'v1' for API Gateway REST API events, 'v2' for HTTP API and function URL events (payload format 2.0). Default: 'v1' |
context | object | Properties of the Lambda context object passed to the handler |
Handlers can return a promise or call the callback. The response is read from the statusCode, headers,
multiValueHeaders, cookies and body of the result, and base64 encoded bodies are decoded. Like API Gateway, a
result without a content-type header is sent as application/json, and with 'v2', a result without a
statusCode is sent as a 200 JSON response.
TestApp
What you can pass as the app option:
- an Express, Koa or Fastify app, or a Hapi server
- an
http.Server, or a Node.js(req, res)request listener - an object with a
fetch(request)method that returns aResponse - a URL string, to send requests to a running server
- a
TestAdapter: an adapter created withlambda(), or your own object with asend()method
interface TestAdapter {
send(request: SentRequest): TestAdapterResponse | Response | Promise<TestAdapterResponse | Response>;
}
interface TestAdapterResponse {
status: number;
headers?: { [name: string]: string | string[] | number | undefined };
body?: unknown;
}
String and Buffer bodies are parsed according to the content-type header. Other values are used as the body as they
are. transformResponse returns the same.
Errors
RoutingError
Thrown by operation methods when the request built for an operation is routed to another operation, or to none. See Operation methods check routing too.
| Property | Description |
|---|---|
operationId | The operation the request was built for |
matchedOperationId | The operation the router matched, or undefined |
request | The SentRequest |
ResponseValidationError
Thrown when a response doesn't match the spec. See Contract testing.
| Property | Description |
|---|---|
response | The TestResponse |
errors | What didn't match, each with a location, like status, headers.content-type or body.name, and a message |